我的指令类似于:
var myApp = angular.module('myApp',[])
.directive("test", function() {
return {
template: '<button ng-click="setValue()">Set value</button>',
require: 'ngModel',
link: function(scope, iElement, iAttrs, ngModel) {
scope.setValue = function(){
ngModel.$setViewValue(iAttrs.setTo);
}
}
};
});
问题在于,如果我在页面中多次使用此指令,则setValue
仅在最后声明的指令上被调用。显而易见的解决方案是使用scope: {}
隔离范围,但是在指令之外无法访问ngModel。
这是我的代码的JSFiddle:http://jsfiddle.net/kMybm/3/
答案 0 :(得分:3)
对于这种情况,ngModel可能不是正确的解决方案。这主要是为了将表单的值绑定到像标记它们的脏和验证......
在这里你可以使用来自隔离范围的双向绑定,如下所示:
app.directive('test', function() {
return {
restrict: 'E',
scope: {
target: '=target',
setTo: '@setTo'
},
template: '<button ng-click="setValue()">Set value</button>',
controller: function($scope) {
$scope.setValue = function() {
$scope.target = $scope.setTo;
};
//HACK: to get rid of strange behavior mentioned in comments
$scope.$watch('target',function(){});
}
};
});
答案 1 :(得分:2)
您需要做的就是将scope: true
添加到指令哈希中。这为您的指令的每个实例创建了一个新的继承子范围,而不是在已经发挥作用的任何范围上不断覆盖“setValue”。
你对隔离范围是正确的。我对新手的建议就是不要永远使用它。
对评论的回应:
我现在更好地理解这个问题了。通过表达式设置值时,它会将其设置为最直接的范围。因此人们通常使用Angular的方法是读取和改变值而不是覆盖值。这需要包含像Object或Array这样的结构中的东西。
请参阅更新的小提琴:
(“foo”通常会通过ngController连接到控制器。)
另一种选择,如果你真的想要“无范围”,那就是不要使用ng-click,只需自己点击即可。