ng-click在指令的模板中不起作用

有angular的noob在这里。 我正在创build一个recursion显示问题和子问题树的指令。 我正在使用模板中的一个链接,在范围内调用一个函数。 出于某种原因,它不会调用editQuestion()方法。

这是代码和小提琴http://jsfiddle.net/madhums/n9KNv/

HTML:

 <div ng-controller="FormCtrl"> <questions value="survey.questions"></questions> </div> 

使用Javascript:

 var app = angular.module('myApp', []); function FormCtrl ($scope) { $scope.editQuestion = function (question) { alert('abc'); }; $scope.survey = { // ... } } 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="danger" ng-click="removeQuestion(question)">remove</a>' + ' <a href="" class="blue" ng-click="editQuestion(question)">edit</a>' + ' <choices value="question.choices"></choices>' + ' </li>' + '</ol>'; return { restrict: 'E', terminal: true, scope: { value: '=' }, 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>' + '' + ' <a href=""' + ' ng-click="addQuestions(choice.questions)"' + ' tooltip="add sub questions">' + ' +' + ' </a>' + '' + ' <questions value="choice.questions"></questions>' ' </li>' + '</ul>'; return { restrict: 'E', terminal: true, scope: { value: '=' }, template: tpl, link: function(scope, element, attrs) { $compile(element.contents())(scope.$new()); } }; }); 

任何帮助理解这一点,将不胜感激。

你有一个范围问题。 由于您在指令中使用了scope: { value: '=' }隔离作用域,因此不再可以访问具有editQuestion控制器作用域。

您需要将editQuestion传递给您的指令范围,以便知道如何调用它。 这通常很容易,但是由于您的无限recursion指令结构,其中的select可以包括问题,所以它有点棘手。 这是一个工作小提琴:

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()); } }; }); 

请注意我们如何在ng-click定位question 。 这是你在callback函数中定位参数的方法。 另请注意, on-edit我们将如何传递给您的choices指令,我们将针对subQuestion 。 这是因为ngRepeat已经保留了ngRepeat ,所以我们需要区分两者。

到目前为止,这可能是我学习Angular的最难的概念。 一旦你了解了范围在控制器,指令和其他指令之间是如何工作的,Angular的世界就是你的。 🙂

这是一个范围问题。 该指令的ng-click调用当前范围的editQuestion&removeQuestion方法,这些方法在指令范围中不存在,就像在包含指令的模块(即父范围)中定义的那样。

你想在指令和父指令之间build立一个绑定,所以当指令调用ngClick函数的时候,它会在托pipe指令的模块上触发。

您可以在指令本身中定义方法,也可以通过指令定义对象的作用域部分设置绑定

这是一个演示程序,演示了在不同的作用域(输出到控制台)

http://plnkr.co/edit/9XfXCpU6lhUOqD6nbVuQ?p=preview

兰登5月10日的答案是正确的。 为了演示目的,我精简了兰登的小提琴代码,并将其从148线的angular度降低到23线的angular度。
我还添加了一些function,可以通过函数调用方法将参数值作为MouseEvent对象传递,并检索函数中的所述值。

这里是JSFIDDLE之后的代码和信用,应该很容易遵循。

http://jsfiddle.net/BeyondLogical/evjzoo30/

–Html–

 <div ng-controller="FormCtrl"> <questions on-edit="editQuestion(ev,question)" ></questions> </div> 

–AngularJS–

 var app = angular.module('myApp', []); function FormCtrl ($scope) { $scope.editQuestion = function (ev,question) { //ev returns a MouseEvent object alert("ev: " + ev); //this is how you get the 'data' attribute set in the span tag below alert("ev-data: " + ev.target.attributes.data.value); }; } app.directive('questions', function($compile) { var tpl = '<span ng-click="onEdit({ev: $event, myName: question})" data="This sentence would probably be replaced with a mustache brace parameter, example: {{someValue}}, returning a value from the scope." style="cursor:pointer;">Click Me</span>'; return { restrict: 'E', terminal: true, scope: { onEdit: '&' }, template: tpl, link: function(scope, element, attrs) { $compile(element.contents())(scope.$new()); } }; }); 

学分,
Langdon- ng-click在指令的模板中不起作用

Mark Rajcok – AngularJS从一个指令中获取$事件 (兰登也得到了一个问题Mark Answers的帮助)

PavanAsTechie – 在非指令控制器函数和Pavan的JSFIDDLE中访问属性值 – http://jsfiddle.net/brettdewoody/FAeJq/ (特别是Pavan的以下代码行): alert(obj.target.attributes.data.value);

对于任何人来说,并试图用你的指令中没有运行的代码来做到这一点,检查你是不是使用选项replace

例如:

 angular.module('app').directive('myDirective', function () { return { template: '<div ng-click="clicked()"></div>', scope: { options: "=" }, replace: true, //<---- Change this to false restrict: 'E', controller: function ($scope) { $scope.clicked = function(){ console.log("Clicked"); } } }; }