【问题标题】:Angular Isolate Scope breaks down?Angular Isolate Scope 崩溃了?
【发布时间】:2014-08-11 01:31:27
【问题描述】:

我有以下标记:

<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 替换它,那么它会呈现结果,但我想使用&amp; 评估在我的主控制器中执行一个函数。

我该怎么办?

【问题讨论】:

  • select 在您的范围定义中缺少单引号 '
  • 什么?什么意思?
  • 应该是 scope: {select: '&amp;'} 而不是 scope: {select: '&}`
  • 那只是一个错字,我马上修正了!我在这里输入示例时忘记关闭引用。另外,如果这是问题所在,Angular 会抛出所有令人讨厌的错误,因为这是语法问题!应用程序运行良好。

标签: angularjs angularjs-scope


【解决方案1】:

改用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 本身定义为范围属性,则必须使用 = 表示法(仅使用 &amp; 表示法,如果您打算将其用作定义的模板中的回调指令),并使用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);

观察一个插值属性。

观察者函数将在下一次 $digest 期间被调用一次 以下编译。然后每当 插值变化。

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

【讨论】:

  • select 属性用于从主控制器调用函数。另外,这不是我的问题。我说如果我使用scope: true,代码就可以正常工作。问题是如果我定义了我的隔离范围,那么它就会崩溃。
  • 另外,$watch 用于监视范围,$observe 用于属性。
  • 阅读我的更新,你部分正确,但 $observe 仅在观察到的属性的插值而不是范围属性发生变化时才会被调用。
  • 但这不是我的问题。在指令内部,如果我控制台记录该值,它确实会改变。问题是在 HTML 中没有分配 scope.matches !它似乎没有价值
  • 前面应该提过,把ng-repeat="match in matches"改成ng-repeat="match in $parent.matches"
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-25
    • 1970-01-01
    相关资源
    最近更新 更多