NG-点击不指令的模板内工作 [英] ng-click doesn't work within the template of a directive

查看:117
本文介绍了NG-点击不指令的模板内工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面角小白。我创建一个指令递归显示问题和子问题一棵树。我正在使用其中要求范围内的功能模板的链接。出于某种原因,但这并没有调用 editQuestion()方法。

Angular noob here. I am creating a directive to recursively display a tree of questions and sub questions. I am using a link in the template which calls a function within the scope. For some reason, it does't call the editQuestion() method.

这里的code和小提琴 http://jsfiddle.net/madhums/n9KNv/

Here's the code and the fiddle http://jsfiddle.net/madhums/n9KNv/

HTML

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

使用Javascript:

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

在了解这将是AP preciated任何帮助。

Any help in understanding this would be appreciated.

推荐答案

您已经有了一个范围问题。既然你使用的隔离范围,在指令与范围:{值:'='} ,它不再具有访问具有控制器的范围 editQuestion

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.

您需要通过 editQuestion 沿着你的指令的范围,因此它知道如何调用它。这通常是pretty容易,但因为你的无限递归指令结构,其中的选择包括问题的,它变得有点棘手。这里有一个工作小提琴:

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/

中的HTML现在包括一个参考 editQuestion

The HTML now includes a reference to editQuestion:

<div ng-controller="FormCtrl">
    <questions value="survey.questions" on-edit="editQuestion(question)"></questions>
</div>

和您的问题指令现在预计在其范围内的 onEdit 属性:

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

请注意我们是如何在 NG-点击目标问题。这就是你的目标在回调函数的参数。还要注意如何在关于修改我们传递到你的选择指令,我们要定位 subQuestion 。这是因为问题里面已经预留了 ngRepeat ,所以我们需要在两者之间进行区分。

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. :)

这篇关于NG-点击不指令的模板内工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆