0

我有一个看起来像这样的指令:

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。​</p>

这是我的代码的 JSFiddle:http: //jsfiddle.net/kMybm/3/

4

2 回答 2

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(){});
      }
   };
});
于 2012-10-24T13:41:41.120 回答
2

您需要做的就是添加scope: true到您的指令哈希。这为指令的每个实例创建了一个新的继承子范围,而不是在任何已经在使用的范围上不断覆盖“setValue”。

你对隔离范围是正确的。我对新手的建议是永远不要使用它。

回复评论:

我现在更好地理解了这个问题。当您通过表达式设置值时,它会将其设置在最直接的范围内。所以人们通常用 Angular 做的是他们读取和改变值而不是覆盖值。这需要将事物包含在某种结构中,例如对象或数组。

查看更新的小提琴:

http://jsfiddle.net/kMybm/20/

(“foo”通常会进入通过 ngController 连接的控制器中。)

另一种选择,如果你真的想做到“无范围”,那就是不使用 ng-click 并自己处理 click 。

http://jsfiddle.net/WnU6z/8/

于 2012-10-25T03:07:15.623 回答