AngularJS - 包装指令
AngularJS - 包装指令
看起来我对指令中的隔离作用域感到困惑,希望你能帮我解决问题。
我尝试将一段包含一些自定义指令的代码封装到一个新的指令中,以减少代码重复。显然,我需要给我的新指令传入一些像ng-model
这样的属性作为参数,以使该指令可重复使用。然而,ng-model
不喜欢表达式(我首先尝试使用ng-model="{{myVariableWhichContainsDesiredNgModelString}}"
),因此我最终看到了这篇文章:AngularJS - 创建一个使用ng-model的指令。
虽然被接受的答案似乎适用于简单的设置,但我编辑了接受答案的plunker,以测试它是否也适用于嵌套指令:(在我的应用程序中,我需要封装来自无法编辑的第三方库的指令)Plunker。在我的代码中,每个指令似乎都生成了自己的作用域,并且在作用域定义中使用=
的双向绑定似乎无法按预期工作。
编辑:由于我的问题不清楚,我编辑了上面的Plunker并重新表述了问题:在Plunker中,我有三个输入字段,它们应该绑定到相同的模型值。这起初是有效的,但是一旦我编辑了第三个输入字段,它就会在其隔离作用域中生成自己的变量,而不是更新初始值。显然,从那时起,第三个输入字段将引用新变量。我如何避免这种行为,并保持输入与$scope.model.name
链接?
观察:从模板中删除隔离作用域指令可以使一切按预期工作...
template: '',
而不是
template: '',
HTML:
指令:
my-input
包含一个修改过的输入字段:
app.directive('myInput', function() { return { restrict: 'E', replace: true, require: 'ngModel', template: '', link: function($scope, elem, attr, ctrl) { console.debug($scope); } }; })
my-isolated-scope-directive
是一个具有自己隔离作用域的占位符指令,用于模拟嵌套指令的行为:
.directive('myIsolatedScopeDirective', function() { return { restrict: 'E', transclude: true, replace: true, scope: { something: '=' }, template: '', link: function($scope, elem, attr, ctrl) { console.debug($scope); } }; })
my-wrapper-directive
封装了前面两个指令,并接受一个参数,该参数应该用作输入字段的ng-model值:
.directive('myWrapperDirective', function() { return { restrict: 'E', transclude: false, replace: true, scope: { myDirectiveVar: '=' }, template: '', link: function($scope, elem, attr, ctrl) { console.debug($scope); } }; });
欢迎提供关于我所忽略的内容的建议和提示。也许我可以以某种方式将ng-model
链接到服务实例,而不使我的指令依赖于该服务?
AngularJS - Wrapping directives
在上述代码中,有三个自定义指令:myInput、myIsolatedScopeDirective和myWrapperDirective。其中,myWrapperDirective通过包裹myIsolatedScopeDirective来实现功能。但是,使用scopes的旧标注方式来实现这个包裹的方法是不推荐的。
为了解决这个问题,可以使用controllerAs和bindToController这两个AngularJS的特性来改进代码。具体实现如下:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function() {
this.model = { name: 'World' };
this.name = "Felipe";
});
app.directive('myInput', function() {
return {
restrict: 'E',
replace: true,
controllerAs: 'app',
require: 'ngModel',
template: '',
controller: function(){
}
};
})
.directive('myIsolatedScopeDirective', function() {
return {
restrict: 'E',
transclude: true,
controllerAs: 'app1',
bindToController: {
something: '='
},
template: '
',
controller: function(){
}
};
})
.directive('myWrapperDirective', function() {
return {
restrict: 'E',
transclude: false,
controllerAs: 'app2',
bindToController: {
myDirectiveVar: '='
},
template: '
'
'
',
controller: function(){
}
};
});
在这段代码中,将myInput指令使用了controllerAs和bindToController特性来替代旧的scopes标注方式。同时,myIsolatedScopeDirective和myWrapperDirective也使用了这两个特性进行了改进。
通过这种改进,可以更好地封装指令,提高指令的可复用性和可维护性。
原文链接:http://plnkr.co/edit/VD0wXO1jivQc3JvfQFTh?p=preview