你有一个范围问题。由于您在指令中使用了隔离范围scope: { value: '=' }
,它不再有权访问您的控制器的范围editQuestion
.
你需要通过editQuestion
沿着你的指令的范围,这样它就知道如何调用它。这通常非常简单,但由于无限递归的指令结构,其中选择可以包含问题,所以它变得有点棘手。这是一个工作小提琴:
http://jsfiddle.net/n9KNv/14/ http://jsfiddle.net/n9KNv/14/
HTML 现在包含对editQuestion
:
<div ng-controller="FormCtrl">
<questions value="survey.questions" on-edit="editQuestion(question)"></questions>
</div>
你的问题指令现在期望onEdit
其范围内的属性:
app.directive('questions', function($compile) {
var tpl = '<ol ui-sortable' +
' ng-model="value"' +
' class="list">' +
' <li ng-repeat="question in value | filter:search"' +
' <a href="" class="question">' +
' {{ question.name }}' +
' </a>' +
' <span class="muted">({{ question.type }})</span>' +
' <a href="" class="blue" ng-click="onEdit({question: question})">edit</a>' +
' <choices value="question.choices" on-edit="onEdit({question: subQuestion})"></choices>' +
' </li>' +
'</ol>';
return {
restrict: 'E',
terminal: true,
scope: { value: '=', onEdit: '&' },
template: tpl,
link: function(scope, element, attrs) {
$compile(element.contents())(scope.$new());
}
};
});
app.directive('choices', function($compile) {
var tpl = '<ul class="abc" ng-repeat="choice in value">'+
' <li>' +
' {{ choice.name }}' +
' <span class="muted">' +
' ({{ choice.questions.length }} questions)' +
' </span>' +
'' +
' <questions value="choice.questions" on-edit="onEdit({subQuestion: question})"></questions>'
' </li>' +
'</ul>';
return {
restrict: 'E',
terminal: true,
scope: { value: '=', onEdit: '&' },
template: tpl,
link: function(scope, element, attrs) {
$compile(element.contents())(scope.$new());
}
};
});
注意我们如何定位question
in the ng-click
。这就是您在回调函数中定位参数的方式。还要注意如何在on-edit
我们正在传递给你choices
指令,我们的目标subQuestion
。这是因为question
已经被保留在里面ngRepeat
,所以我们需要区分两者。
这可能是迄今为止我在 Angular 中学习的最难的概念。一旦您了解了控制器、指令和其他指令之间的作用域如何工作,Angular 的世界就属于您了。 :)