使用`ng-repeat`范围函数的angularjs未调用

时间:2016-01-26 09:30:14

标签: angularjs angular-directive

我从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

2 个答案:

答案 0 :(得分:1)

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

这是一个有效的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,它解释了指令范围

答案 1 :(得分:1)

您的指令中有一个独立的范围,因此您不能仅引用范围外的值。你可能想要的是将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()