繁体   English   中英

创建新范围时,带有子指令的父级将不起作用

[英]parent with child directives won't work when creating new scope

我创建了一个父指令,该指令可以从给定的URL检索数据,这很好。 第二步,我想在几个子指令之间分配数据,例如:

<parent data="some/url/with/json/response">
  <child data="data[0]"></child>
  <child data="data[1]"></child>
  ...
</parent>

这也很好。 但是,在创建另一组指令时,旧数据将被覆盖,因为父指令不会创建新的作用域,而是会覆盖主作用域中的所有内容。 当在指令中指定以下行之一时,根本不显示任何数据(现在出现错误msg):

scope: true,
//or
scope: {},

这是错误情况的一个笨拙的示例: http ://plnkr.co/edit/GWcLrhaUHNLPWNkOHIS8?p=preview顶部应显示“ This is working”。

因此,问题是:有谁知道我可以如何强制parent指令创建所有子元素都可以访问的新作用域?

在子指令中,应在父作用域上评估字符串,如下所示:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
});

app.directive('parentBindScope', function($timeout) {
  return {
    restrict: 'E',
    transclude: true,
    scope: true,
    template: '<div ng-transclude></div>',
    controller: function($scope, $attrs) {
      if($attrs.working) {
          $scope.working = {key: 'this is working'};
      } else {
        $scope.working = { key: 'something else' }
        $timeout(function(){
          $scope.working = {key: 'this is not working'};
        },1000)

      }

    }
  }
});

app.directive('childBindScope', function($parse) {
  return {
    restrict: 'E',
    template: '<div>child-template: {{data}}</div>',
    controller: function($scope, $attrs) {
      $scope.$watch('$parent.' + $attrs.data, function() {
        $scope.data = $scope.$parent.$eval($attrs.data);
      });
    },
    link: function(scope, element, attrs) {
      console.log('data: ' + JSON.stringify(scope.data));
    }
  }
})

采用:

scope: false

在您的子范围内 ,保留子元素中父元素的范围。

使用true或{}称为isolateScope,这是有原因的。 保护子范围。

问题在于父指令正在继承作用域(控制器的作用域),因此所有父指令本质上都共享同一作用域。 当父母双方共享同一个范围时,要执行的最后一个指令(不具有“ working”属性的父母指令)将在共享范围内定义“ working”属性,该属性在链接实现中分配$ scope.working =“ this不管用”。

<!-- bind object to child scope -->
<parent-bind-scope working=true>
  Should be working: 
  <child-bind-scope data="working"></child-bind-scope>
</parent-bind-scope>

<br>

<parent-bind-scope>
  Should not be working:
  <child-bind-scope data="working"></child-bind-scope>
</parent-bind-scope>

如果在分配$ scope.working时发出警报,则可以看到它正在执行if条件的两个分支(else控制流位于最后):

controller: function($scope, $attrs) {
  if($attrs.working) {
    alert('working attribute exists');
    $scope.working = {key: 'this is working'};
  } else {
    alert('working attribute does not exist');
    $scope.working = {key: 'this is not working'};
  }

}

我终于找到了一个看起来也不错的解决方案。 因为plunker默认情况下是通过使用angular 1.2创建脚本的,所以我没有较早找到此解决方案(显然它仅在1.3.x中有效)。 现在,每个父指令确实创建了自己的作用域,而子代也这样做。 然后,通过使用此表示法(带有$ parent),将显示正确的数据:

<parent-bind-scope working=true>
  Should be working:
  <child-bind-scope data="$parent.working"></child-bind-scope>
</parent-bind-scope>

另请参阅: http : //plnkr.co/edit/NkVxpjryD8YQm9xovw4M?p=preview

在使用Remco的答案并为孩子创建隔离范围时,我必须使用$ parent。$ parent来获得相同的结果,因此这是该解决方案的重要一步。

另外:使用ng-repeat时很奇怪,在我的真实代码中,我现在必须要做$ parent。$ parent。$ parent这样的工作:

//not the exact code
<parent parentdata="/url/with/data">
    <div ng-repeat="i in $parent.range($parentdata.data.cols.length) track by $index">
        <child data1="$parent.$parent.$parent.parentdata.cols[$index]"
               data2="$parent.$parent.$parent.parentdata.rows[$index]"/>
    </div>
</parent>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM