角隔离作用域崩溃了



我有以下标记:

<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();
            })
        }
    }
}

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

我该怎么办?

使用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);
            });
        }
    }
}

UPDATE:同样地,如果你将select本身定义为作用域属性,你必须使用=表示法(如果你打算将其用作指令中定义的模板中的回调,则只能使用&表示法),并且使用scope.$watch(),而不是attr.$observe()。由于attr.$observe()只用于插值更改{{}},而$watch用于scope属性本身的更改。

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文档说明:

观察美元(关键,fn);

观察到一个插入的属性。

观察者函数将在下一个$digest中调用一次后编译。对象时调用观察者插值值变化

在指令定义中定义scope的问题中没有定义这样的范围属性。

如果不需要隔离作用域,可以使用$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

最新更新