角隔离范围破裂?

时间:2014-08-11 01:31:28

标签: angularjs angularjs-scope

我有以下标记:

<div class="controller" ng-controller="mainController">
    <input type="text" ng-model="value">
    <div class="matches" 
        positions="{{client.positions | filter:value}}" 
        select="selectPosition(pos)">

        <div class="match" 
            ng-repeat="match in matches" 
            ng-click="select({pos: match})"
            ng-bind="match.name">

然后,我的matches指令里面有

app.directive('matches', function()
{
    return {
        scope: {
            select: '&'
        },
        link: function(scope, element, attrs)
        {
            scope.matches = [];
            attrs.$observe('positions', function(value)
            {
                scope.matches = angular.fromJson(value);
                scope.$apply();
            })
        }
    }
}

当我这样做时,我可以控制日志scope.matches,并且它会随着我输入的值而改变。但是,最后一个div .match并没有呈现任何内容!如果我删除scope: {...}并将其替换为scope: true,那么它会渲染结果,但我想使用&评估来执行主控制器中的函数。

我该怎么办?

2 个答案:

答案 0 :(得分:0)

使用scope.$watch代替,只要对该属性进行更改,您就可以观看属性select

app.directive('matches', function()
{
    return {
        scope: true,
        link: function(scope, element, attrs)
        {
            scope.matches = [];
            scope.$watch(attrs.select, function(value) {
              scope.matches = angular.fromJson(value);
            });
        }
    }
}

更新:同样,如果您将select本身定义为范围属性,则必须使用=表示法(仅使用&表示法,如果您打算将其用作范围属性在指令中定义的模板中回调,并使用scope.$watch(),而不是attr.$observe()。由于attr.$observe()仅用于插值更改{{}},因此$ watch用于更改范围属性本身。

app.directive('matches', function()
{
    return {
        scope: {select: '='},
        link: function(scope, element, attrs)
        {
            scope.matches = [];
            scope.$watch('select', function(value) {
              scope.matches = angular.fromJson(value);
            });
        }
    }
}

AngularJS文档声明:

$ observe(key,fn);

  

观察插值属性。

     

观察者函数将在下一个$摘要期间调用一次   编译后。然后每当调用观察者时   插值变化。

在您的问题中定义的范围属性不是在指令定义中定义scope

答案 1 :(得分:0)

如果您不需要隔离范围,则可以使用$parse代替&评估,如下所示:

var selectFn = $parse(attrs.select);
scope.select = function (obj) {
  selectFn(scope, obj);
};

示例Plunker: http://plnkr.co/edit/QZy6TQChAw5fEXYtw8wt?p=preview

但是如果您更喜欢隔离范围,则必须转换子元素并正确分配指令的范围,如下所示:

app.directive('matches', function($parse) {
  return {
    restrict: 'C',
    scope: {
      select: '&',
    },
    transclude: true,
    link: function(scope, element, attrs, ctrl, transcludeFn) {
      transcludeFn(scope, function (clone) {
        element.append(clone);
      });

      scope.matches = [];
      attrs.$observe('positions', function(value) {
        scope.matches = angular.fromJson(value);
      });
    }
  }
});

示例Plunker: http://plnkr.co/edit/9SPhTG08uUd440nBxGju?p=preview