1

在使用 ngRepeat 时,我有一个从数组中加载四个项目的无序列表。列表项中的锚标记在 ngClick 属性中具有触发消息的功能。像这样使用时,函数调用效果很好:

<ul>
  <li ng-repeat="n in supsNames">
    <a ng-click="myAlert(n.name)">{{n.name}}</a>
  </li>
</ul>

我创建了一个简单的指令,用于插入带有列表项的无序列表。该列表加载得很好,但我之前提到的相同功能没有启动。代码如下:

<div list items="supsNames">
  <a ng-click="myAlert({{item.name}})">{{item.name}}</a>
</div>

这是我的 javascript 和 angularjs 代码:

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

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

$scope.title = 'ngClick within ngTransclude';
$scope.supsNames = [
    {"name" : "Superman"},
    {"name" : "Batman"},
    {"name" : "Aquaman"},
    {"name" : "Flash"}
  ];

  $scope.myAlert = function(name) {
    alert('Hello ' + name + '!');
  };
});

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

return {

restrict: 'A',
scope: {
  items: '='
},
templateUrl: 'list.html',
transclude: true,
link: function(scope, element, attrs, controller) {
  console.log(scope);
}

};

});

我也有一个 plnkr,以防你想看看我试图做什么: http ://plnkr.co/edit/ycaAUMggKZEsWaYjeSO9?p=preview

谢谢你的帮助。

4

3 回答 3

2

我让 plunkr 工作了。我不确定它是否正是你要找的。我复制了下面的主要代码更改。

这是plunkr:

http://plnkr.co/edit/GEiGBIMywkjWAaDMKFNq?p=preview

修改后的指令现在看起来像这样:

app.directive('list', function() {
  return {
    restrict: 'A',
    scope: {
      items: '=', 
      ctrlFn: '&' //this function is defined on controller
    },
    templateUrl: 'list.html',
    transclude: true,
    link: function(scope, element, attrs, controller) {

      //directive fn that calls controller defined function
      scope.dirFn = function(param) {
        if(scope.ctrlFn && typeof scope.ctrlFn == 'function') { //make sure its a defined function
          scope.ctrlFn( {'name': param} ); //not sure why param has to be passed this way
        }
      }

    }

  };

});

下面是它在绑定到控制器的 html 文件中的调用方式:

<div list items="supsNames" ctrl-fn="myAlert(name)">
  <a ng-click="dirFn(item.name)">{{item.name}}</a>
</div>

我认为之前发生的事情是您试图在指令的隔离范围内使用控制器中定义的函数,因此它不起作用 - 该函数在指令中未定义。所以我所做的就是在指令中添加另一个参数,该参数接受带有“&”的方法绑定(我认为这就是它的名称)。

所以基本上你将你的控制器方法传递给指令,然后这个方法被我创造性地命名为“dirFn”的指令定义的方法调用。我不知道这本身是否是最好的方法,但我已经在现有项目中使用它并取得了很好的效果;)

于 2013-12-09T18:55:21.067 回答
1

您需要将函数传递给指令

scope: {
   items: '=', 'myAlert': '='
},
于 2013-12-08T09:21:44.943 回答
0

指令模板内的ng-repeat插入一个新范围,它需要手动调用 transclude 函数才能工作。我建议删除ng-repeat并手动传递控制器范围的副本并在每个副本上设置项目:

for(var i=0,len=scope.items.length;i<len;i++){
    var item=scope.items[i];
    var itemScope=scope.$parent.$new();
    $transcludeFn(itemScope, function (clone,scope) {
                // be sure elements are inserted
                // into html before linking
                scope.item=item;
                element.after(clone);
    });
  };

我编辑了 pluker,希望对您有所帮助:http ://plnkr.co/edit/97ueb8SFj3Ljyvx1a8U1?p=preview

有关嵌入的更多信息,请参阅:嵌入:$transcludeFn

于 2016-03-04T13:27:09.170 回答