带有bindToController的指令无法从子指令获取数据

时间:2015-09-18 18:30:18

标签: javascript angularjs angularjs-directive angularjs-scope angularjs-ng-transclude

我要编写一个指令,从其子指令的输入构建一个对象并推送它 到作为参数提供的数组。类似的东西:

$ git checkout -b test
Switched to a new branch 'test'

$ git push --verbose -u origin test
Pushing to https://user@bitbucket.org/user/repo.git
Password for 'https://user@bitbucket.org': 
Total 0 (delta 0), reused 0 (delta 0)
POST git-receive-pack (183 bytes)
remote: 
remote: Create pull request for test:
remote:   https://bitbucket.org/user/repo/pull-requests/new?source=test&t=1
remote: 
To https://user@bitbucket.org/user/repo.git
 * [new branch]      test -> test
Branch test set up to track remote branch test from origin.
updating local tracking ref 'refs/remotes/origin/test'

我希望收集如下数据:

<aggregate-input on="SiteContent.data.objList">
    <p aggregate-question>Question text</p>
    <input aggregate-answer ng-model="answer" type="text" />
</aggregate-input>
<aggregate-input on="SiteContent.data.objList">
    <p aggregate-question>Question text 2</p>
    <input aggregate-answer ng-model="answer" type="text" />
</aggregate-input>

这里是plunker with the code

  • 更新1:@jrsala包括范围和bindToController语法更改

我无法弄清楚这些指令应该如何沟通的方式。我期待SiteContent.data.objList === [ {question: 'Quesion text', answer: 'user input'}, {question: 'Quesion text 2', answer: 'user input 2'}, ]; 链接中定义的对象将在每个指令的范围内被隔离并推送到input对象 提供。结果是on对象在所有实例之间共享,并且只有一个对象获得 曾被推到阵列。

我猜测抄袭范围规则令我困惑,但我真的不知道在哪里。有任何想法吗?谢谢!

1 个答案:

答案 0 :(得分:1)

第一个问题:您的aggregate-input指令指定了一个没有绑定属性的隔离范围,但您仍然在元素上使用on属性并带有指令:

<aggregate-input on="SiteContent.data.objList">

但是在你的JS中,

{
    restrict: 'E',
    scope: {},
    controller: aggregateInputController,
    controllerAs: 'Aggregate',
    bindToController: { on: '=' },
    /* */
}

而你需要的是

{
    restrict: 'E',
    scope: { on: '=' },
    controller: aggregateInputController,
    controllerAs: 'Aggregate',
    bindToController: true // BOOLEAN REQUIRED HERE, NO OBJECT
}

根据bindToController上的the spec段落,

  

当使用隔离范围作为组件(参见上文)并使用controllerAs时,bindToController:true将允许组件将其属性绑定到控制器,而不是范围。实例化控制器时,隔离范围绑定的初始值已经可用。

然后你不需要将on属性分配给你的控制器,它是由Angular为你完成的(我也不明白为什么你做this.on = this.on || [],{{1部分看起来不需要我。)

我想你可以将它应用于其余的代码,这应该是一个开始。我会去寻找更多问题。

编辑:我发现了几个问题:

  • 如果this.on ||的范围被隔离,则在编译指令时无法访问siteContent控制器,并且在评估{{1}时Angular无提示失败(如始终...)将它传递给子指令。我通过从其定义中删除SiteContent来修复此问题。

  • 有必要将SiteContent.data.objList的功能移到scope: {},因为像往常一样,子控制器在链接函数之前执行,并且因为aggregateInputLink指令使控制器中的调用aggregateInputController,在父指令后链接功能中分配的aggregateQuestion尚不存在。

  
InputCtrl.changeValue('question', elem.text());

提醒一下:控制器以预购方式执行,并在遍历指令树期间以后序方式链接功能。

  • 最后,在此之后,scope.input控制器的数据未获得呈现属性,因为用于在function aggregateInputController($scope) { $scope.input = {}; this.on.push($scope.input); this.changeValue = function changeValue(field, value) { $scope.input[field] = value; }; } 中迭代的集合错误地SiteContent而不是{{1 }}。

链接到最终plunker