angularjs 使用 `ng-repeat` 作用域函数未被调用

angularjs using `ng-repeat` scope function not called

我正在从 ng-repeat 迭代器调用一个方法。但我没有得到范围内调用的方法。有人帮我解决这个问题吗?

这是我的 js :

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {

  $scope.levels = {'title':'Select a Level', item:["Low", "Medium", "Hight"], show:false };
  $scope.stages = ["Open", "Inprogress", "Closed"];
  $scope.colors = ["Red", "Yellow", "Blue"];

  $scope.levelHandler = function ( level ) {
    console.log( level ); //not called
  }

});


app.directive('dropDown', function () {

  return {

    replace:true,
    scope :{
      data:"="
    },
    template : $('#dropdown').html(),
    link:function (scope, element, attrs) {

      var title = element.find('.title');
      var listHolder = element.find('ul');
      var parent = title.add(listHolder);
      var list = element.find('li');

      title.on('click',  function (e) {
         scope.data.show = !scope.data.show;
         scope.$apply();

      });

      parent.add(listHolder).on('mouseleave',  function (e) {
         scope.data.show = !scope.data.show;
         scope.$apply();
      });


    }

  }

})

HTML :

<body ng-controller="MainCtrl">
    <form name="myform">

      <drop-down data="levels" ></drop-down>

    </form>
    <script type="text/ng-template" id="dropdown">

    <div class="formGroup">
        <h4 class="title">{{data.title}}</h4>
        <ul ng-show='data.show'>
          <li ng-repeat="level in data.item" ng-click="levelHandler( level )" >{{level}}</li>
        </ul>
      </div>

  </script>
  </body>

Live Demo

你的指令有一个独立的范围,因此你需要将外部函数从控制器绑定到指令中,它会按预期工作。

这是一个有效的 plnkr

scope :{
    data:"=",
    func: '='
}

模板:

<drop-down func='levelHandler' data="levels" ></drop-down>
..
<li ng-repeat="level in data.item" ng-click="func( level )" >{{level}}</li>

这里有一个很好的tutorial解释了指令作用域

你的指令中有一个独立的作用域,所以你不能只引用外部作用域中的值。您在这里可能想要的是将 levelHandler 函数传递给 dfirective:

app.directive('dropDown', function () {

  return {

    replace:true,
    scope :{
      data:"=",
      levelHandler: "="
    },
    template : $('#dropdown').html(),
    link:function (scope, element, attrs) {
...
})

然后在你的 html:

<drop-down data="levels" level-handler="levelHandler" ></drop-down>

另一种方法是根本不使用隔离作用域,而只是通过 attrs.data 访问数据。这有一个缺点,如果它是一个表达式,你必须自己评估它,但有时它可能更可取。

顺便说一句,通常最好在模板中使用 ng-clickng-mouseleave 而不是绑定事件。这样你就永远不必担心自己给 scope.$apply() 打电话。