带有 bindToController 的指令无法从子指令中获取数据
directive with bindToController can't get data from child directives
我正在尝试编写一个指令,该指令从其子指令的输入构建一个对象并将其推送
到作为参数提供的数组。类似于:
<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>
我希望收集如下数据:
SiteContent.data.objList === [
{question: 'Quesion text', answer: 'user input'},
{question: 'Quesion text 2', answer: 'user input 2'},
];
- 更新 1:@jrsala 包含范围和 bindToController 语法更改
我无法确定这些指令的通信方式。我期待 input
link 中定义的对象将在每个指令的范围内被隔离并推送到 on
对象
假如。结果是 input
对象在所有实例之间共享,只有一个对象得到
曾被推入数组。
我猜被嵌入的范围规则让我感到困惑,但我真的不知道在哪里。有任何想法吗?谢谢!
第一个问题:您的 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
}
根据 the spec 关于 bindToController
的段落,
When an isolate scope is used for a component (see above), and controllerAs is used, bindToController: true will allow a component to have its properties bound to the controller, rather than to scope. When the controller is instantiated, the initial values of the isolate scope bindings are already available.
那么你就不需要将on
属性分配给你的控制器了,它是由Angular为你完成的(我也不明白你为什么这样做this.on = this.on || []
,this.on ||
部分对我来说似乎没有必要)。
我想您可以将其应用于其余代码,这应该是一个开始。我要寻找更多问题。
编辑: 我发现的其他几个问题:
如果 siteContent
的作用域被隔离,那么当编译指令时 SiteContent
控制器不可访问并且 Angular 静默失败(就像总是.. .) 在评估 SiteContent.data.objList
以将其传递给子指令时。我通过从定义中删除 scope: {}
来解决这个问题。
有必要将 aggregateInputLink
的功能移至 aggregateInputController
,因为像往常一样,子控制器在 link 函数之前执行,并且由于aggregateQuestion
指令在其 控制器 中调用 InputCtrl.changeValue('question', elem.text());
,在父指令 post-[=74 中分配给 scope.input
=]函数还不存在。
function aggregateInputController($scope) {
$scope.input = {};
this.on.push($scope.input);
this.changeValue = function changeValue(field, value) {
$scope.input[field] = value;
};
}
提醒一下:在遍历指令树期间,控制器以预序方式执行,link 以 post 方式运行。
- 最后,在那之后,
SiteContent
控制器的数据没有得到呈现 属性 因为在 ng-repeat
中用于迭代的集合被错误地 SiteContent.objList
而不是 SiteContent.data.objList
.
Link 到最终 plunker
我正在尝试编写一个指令,该指令从其子指令的输入构建一个对象并将其推送 到作为参数提供的数组。类似于:
<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>
我希望收集如下数据:
SiteContent.data.objList === [
{question: 'Quesion text', answer: 'user input'},
{question: 'Quesion text 2', answer: 'user input 2'},
];
- 更新 1:@jrsala 包含范围和 bindToController 语法更改
我无法确定这些指令的通信方式。我期待 input
link 中定义的对象将在每个指令的范围内被隔离并推送到 on
对象
假如。结果是 input
对象在所有实例之间共享,只有一个对象得到
曾被推入数组。
我猜被嵌入的范围规则让我感到困惑,但我真的不知道在哪里。有任何想法吗?谢谢!
第一个问题:您的 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
}
根据 the spec 关于 bindToController
的段落,
When an isolate scope is used for a component (see above), and controllerAs is used, bindToController: true will allow a component to have its properties bound to the controller, rather than to scope. When the controller is instantiated, the initial values of the isolate scope bindings are already available.
那么你就不需要将on
属性分配给你的控制器了,它是由Angular为你完成的(我也不明白你为什么这样做this.on = this.on || []
,this.on ||
部分对我来说似乎没有必要)。
我想您可以将其应用于其余代码,这应该是一个开始。我要寻找更多问题。
编辑: 我发现的其他几个问题:
如果
siteContent
的作用域被隔离,那么当编译指令时SiteContent
控制器不可访问并且 Angular 静默失败(就像总是.. .) 在评估SiteContent.data.objList
以将其传递给子指令时。我通过从定义中删除scope: {}
来解决这个问题。有必要将
aggregateInputLink
的功能移至aggregateInputController
,因为像往常一样,子控制器在 link 函数之前执行,并且由于aggregateQuestion
指令在其 控制器 中调用InputCtrl.changeValue('question', elem.text());
,在父指令 post-[=74 中分配给scope.input
=]函数还不存在。
function aggregateInputController($scope) {
$scope.input = {};
this.on.push($scope.input);
this.changeValue = function changeValue(field, value) {
$scope.input[field] = value;
};
}
提醒一下:在遍历指令树期间,控制器以预序方式执行,link 以 post 方式运行。
- 最后,在那之后,
SiteContent
控制器的数据没有得到呈现 属性 因为在ng-repeat
中用于迭代的集合被错误地SiteContent.objList
而不是SiteContent.data.objList
.
Link 到最终 plunker