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

时间:2015-01-07 10:30:59

标签: javascript angularjs data-binding angularjs-directive angularjs-scope

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

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

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

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

以下是错误情况的一个例子:http://plnkr.co/edit/GWcLrhaUHNLPWNkOHIS8?p=preview 顶部应该有“这是工作”。

所以问题是:有没有人知道如何强制父指令创建一个所有子元素都可以访问的新范围?

4 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

使用:

scope: false

子范围中保留范围与子元素中的父元素。

使用true或{}称为isolateScope,这就是为什么它是这样的。保护儿童范围。

答案 2 :(得分:0)

问题是父指令是继承范围(控制器的范围),因此所有父指令基本上共享相同的范围。当两个父项共享相同的作用域时,要执行的最后一个指令(没有“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'};
  }

}

答案 3 :(得分:0)

我终于找到了一个看起来不错的解决方案。因为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>