You've got a scope issue. Since you used isolated scope in your directive with scope: { value: '=' }
, it no longer has access to your controller's scope that has editQuestion
.
You need to pass editQuestion
along to your directive's scope so it knows how to call it. This is typically pretty easy, but because of your infinitely recursive directive structure where choices can include questions, it gets a bit trickier. Here's a working fiddle:
http://jsfiddle.net/n9KNv/14/
The HTML now includes a reference to editQuestion
:
<div ng-controller="FormCtrl">
<questions value="survey.questions" on-edit="editQuestion(question)"></questions>
</div>
And your questions directive now expects an onEdit
attribute in its scope:
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());
}
};
});
Notice how we're targeting question
in the ng-click
. This is how you target arguments in callback functions. Also notice how in the on-edit
we're passing to your choices
directive, we're targeting subQuestion
. This is because question
is already reserved inside of the ngRepeat
, so we need to differentiate between the two.
This was probably the hardest concept for me to learn in Angular so far. Once you understand how scope works between controllers, directives, and other directives, the world of Angular is yours. :)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…