Angular指令ng-click无法工作

4

Plunker

我有一个包含指令的外部控制器。该指令在其视图中获取进程点列表并生成链接,您可以选择每个链接。它在链接函数中正确设置HTML,但链接的ng-click操作不起作用。

有任何想法?:)

非 Plunkering 代码

HTML

<!DOCTYPE html>
<html>

  <head><link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
        <script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
    <script src="script.js"></script>
  </head>

  <body ng-app="app">
    <div ng-controller="widget">
      <process stages="production" at="productionAt"></process>
    </div>
  </body>

</html>

JS

angular.module('app', ['app.directives', 'app.controllers']);

angular.module('app.controllers', [])
 .controller('widget', function($scope) {
    var selectStage = function () {
      alert(this.label + " selected.");
      $scope.processAt = this;
    }

    $scope.production = [
        {label: "Starting", select: selectStage}
      , {label: "Fermenting", select: selectStage}
      , {label: "Pouring",     select: selectStage}
      , {label: "Beer!",  select: selectStage}
    ];

    $scope.productionAt = $scope.production[0];
 });

angular.module('app.directives', [])
 .directive('process', function() {
    return {
        restrict: 'E'
      , replace: true
      , template: '<ol class="nav nav-pills"></ol>'
      , scope: {
            stages: "="
          , at: "="
        }
      , link: function postLink(scope, element, attrs) {
          for (var i = 0; i < scope.stages.length; i++) {
            var $stage = $('<li ng-click="stages['+i+'].select()"><a>'+scope.stages[i].label+'</a></li>');
            if (scope.at == scope.stages[i]) {
              $stage.addClass('active');
            }
            $(element).append($stage);
          }
        }
    }
  });

尝试创建一个返回ng-click值的函数。也许与JavaScript闭包有关(http://www.mennovanslooten.nl/blog/post/62)。 - Martijn
2个回答

8
为了让ng-click指令生效,它需要首先被angular基础设施处理(“编译”)。因此,您可以在指令模板中使用ng-repeat,而不是手动创建angular无法识别的li元素(无需手动创建DOM元素),具体如下:
angular.module('app.directives', [])
 .directive('process', function() {
    return {
        restrict: 'E'
      , replace: true
      , template: '<ol class="nav nav-pills"><li ng-class="{active: stage==at}" ng-click="stage.select()" ng-repeat="stage in stages"><a>{{stage.label}}</a></li></ol>'
      , scope: {
            stages: "="
          , at: "="
        }
    }
  });

修改后的plunker链接:http://plnkr.co/edit/SW1Ph0nIjVYW3UzixtBx?p=preview 我认为这是最优雅的解决方案。当然,您可以将模板移到外部文件中,并通过templateUrl进行引用。
或者,在手动添加li项目后,您可以在元素上使用$compile服务,但感觉像是一个hack。

1
它优雅、简短,不需要jQuery。+1 - pkozlowski.opensource
太棒了,非常感谢。我肯定没有按照“Angular方式”去做事情。 - jtfairbank

2

工作链接 http://plnkr.co/edit/3zuDuQDjhA5UY5nLD09Z?p=preview

请在url指令中进行以下更改

angular.module('app.directives', [])
 .directive('process', function($compile) {
    return {
        restrict: 'E'
      , replace: true
      , template: '<ol class="nav nav-pills"></ol>'
      , scope: {
            stages: "="
          , at: "="
        }
      , link: function postLink(scope, element, attrs) {
          for (var i = 0; i < scope.stages.length; i++) {
            var $stage = $('<li ng-click="stages['+i+'].select()"><a>'+scope.stages[i].label+'</a></li>');
            if (scope.at == scope.stages[i]) {
              $stage.addClass('active');
            }
            $(element).append($stage);
            $compile($(element))(scope);
          }
        }
    }
  });

我已经注入了 $compile 并添加了一行代码 $compile($(element))(scope);。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接