在父指令和子指令之间共享变量

时间:2013-11-26 01:41:34

标签: angularjs angularjs-directive

我有2个指令,一个表示数据列表的指令,而另一个表示列表所需的控件过滤器。像这样......

  <item-list data-items="items">
    <list-filters></list-filters>
  </item-list>

我想要做的是使用父指令“itemList”,在其范围内维护一些过滤器对象,然后让子指令通过链接函数直接修改该对象。 / p>

以下是2条指令

app.directive('itemList', function() {
  return {
    restrict: 'E',
    scope: {
      items: '='
    },
    transclude:true,
    controller: function($scope){

      $scope.filter = {};

      $scope.add = function(){
        var length = $scope.items.length+1;
        $scope.items.push({
          id: length,
          name: 'item' + length
        });
      };
    },
    templateUrl: 'list.html'
  };
}); 

app.directive('listFilters', function() {
  return {
    restrict: 'E',
    templateUrl: 'list-filters.html',
    require: '^itemList',
    link: function(scope, elem, attr, itemList){

      itemList.$watch('items', function(){
        scope.items = itemList.items;
      });


      scope.change = function(item){
        console.log('change', item);
        itemList.filter = item;
      };

      scope.filter = itemList.filter; // ?? why can't I do this

    }
  }
});

我无法弄清楚如何从itemList指令获取过滤器对象,有什么建议吗?

http://plnkr.co/edit/mVSoxqpeYhwpMxYJFNwj?p=info

3 个答案:

答案 0 :(得分:1)

link函数中的参数itemList是实际的控制器对象,你想要的是在item-list中创建一个允许修改过滤器变量的接口。

app.directive('itemList', function() {
  return {
    restrict: 'E',
    scope: {
      items: '='
    },
    transclude:true,
    controller: function($scope){
      $scope.filter 
      $scope.add = function(){
        var length = $scope.items.length+1;
        $scope.items.push({
          id: length,
          name: 'item' + length
        });
      };

      this.updateFilterList = function(newList){
          $scope.apply(function(){$scope.filter = newList;});
      }
    },
    templateUrl: 'list.html'
  };
}); 




app.directive('listFilters', function() {
  return {
    restrict: 'E',
    templateUrl: 'list-filters.html',
    require: '^itemList',
    link: function(scope, elem, attr, itemList){

      itemList.$watch('items', function(){
        scope.items = itemList.items;
      });


      scope.change = function(item){
        console.log('change', item);
        itemList.updateFilterList(item);
      };

      //call the interface to update the filter list with whatever new object
      itemList.updateFilterList( scope.filter );
    }
  }
});

你明白了,它基本上是在父控制器中创建一个允许修改其状态的接口,并让子指令使用该接口。

答案 1 :(得分:0)

你的“listFilters”指令不会创建一个新的作用域,所以你应该能够只使用listFilters中的“scope.filters”访问你在itemList控制器中设置的$ scope.filters对象指令的链接功能。

答案 2 :(得分:0)

我修改了一点代码 见http://plnkr.co/edit/QF6p3JXQD3zT6Yio2f4U?p=preview
您的子指令范围可以访问父指令的属性 但是,如果更改了child指令的属性,则父指令的属性不会自动更改其值 因此,如果子范围发生更改,则应手动更改父作用域的属性:

scope.$watch('filter', function(val, oldval) {
        scope.$parent.filter = val;
      })