从深层嵌套的指令调用父作用域函数

时间:2014-10-21 01:03:49

标签: javascript angularjs angularjs-directive

我有一个无限嵌套的数据结构,其中有一个顶层对象,它有一个对象集合,每个对象也可以有一个对象集合。

我需要遍历这个树,我目前正在这样做:

collection.js

app.directive('collection', function() {
  return {
    restrict: 'E',
    replace: true,
    scope: {
      collection: '='
    },
    templateUrl: 'collection.html'
  };
});

collection.html

<ul>
  <member ng-repeat="member in collection" member="member"></member>
</ul>

member.js

app.directive('member', function($compile) {
  return {
    restrict: 'E',
    replace: true,
    scope: {
      member: '='
    },
    templateUrl: 'member.html',
    link: function(scope, element, attrs) {
      var collection = '<collection collection="member.children"></collection>';

      if (scope.member.children) {
        $compile(collection)(scope, function(cloned, scope) {
          element.append(cloned);
        });
      }
    }
  };
});

member.html

<li>
  {{ member }} 
</li> 

的index.html

<div data-ng-controller="collectionController">
  <collection collection="collection"></collection>
</div>

我需要能够点击一个成员,无论它是如何嵌套的,并将控制器的selectedMember属性设置为该成员。

这样的事情:

app.controller('collectionController', function($scope, collection) {

  collection.getCollection().then(function(collection) {
    $scope.collection = collection;
  });

  $scope.selectMember = function(member) {
    $scope.selectedMember = member;
  };

});

由于我调用了父作用域(控制器)中定义的函数,我想我需要传递selectMember函数,如下所示:

的index.html

...
<collection collection="collection" select-member="selectMember"></collection>
...

collection.html

<member ng-repeat="member in collection" member="member" 
  select-member="selectMember()" ng-click="selectMember(member)">
</member>

collection.js

...
scope: {
  collection: '=',
  selectMember: '&selectMember'
}
...

member.js

...
scope: {
  member: '=',
  selectMember: '='
}
...

我似乎无法正确触发该功能并设置控制器范围的selectedMember属性。传递给selectMember函数的参数未定义。

我认为很明显,我对范围有些误解,但我必须解决的问题的嵌套性质并不会让事情变得更容易。

有什么想法吗?

编辑: 继承人:http://plnkr.co/edit/JfxpoLLgpADs9RXSMife

1 个答案:

答案 0 :(得分:4)

是的,我认为您采取的方法是正确的 - 即从外部范围传递点击处理程序。如何传递处理程序只是一些小混乱。我希望你创造了一个掠夺者,但我会试图失明。 :)

<强>的index.html

<collection collection="collection" select-member="selectMember(member)"></collection>

collection.html 模板

<member ng-repeat="item in collection" 
        member="item" 
        select-member="selectMember({member: member})"></member>

<强> collection.js

...
scope: {
  collection: '=',
  selectMember: '&'
}
...

member.html 模板

<li ng-click="selectMember({member: member})>{{ member }}</li> 

此外,当您为<collection>添加member.children时:

<collection collection="member.children" 
            select-member="selectMember({member: member})"></collection>

<强> member.js

...
scope: {
  member: '=',
  selectMember: '&'
}
...

修改

好的,这不是一件小事:)但它很有趣。

一些修改:

  1. select-member不应该只是&#34;传递一个功能&#34;因为我错误地建议。
  2. ng-clickmember上宣布时没有正确射击 - 它正在为孩子和父母开火。我将其移至member.html模板。
  3. 为清楚起见,我使用了item ng-repeatng-repeat="item in collection"
  4. 我正在纠正上述代码。我还创建了一个你plunker的分支。