【问题标题】:Triggering a function with ngClick within ngTransclude在 ngTransclude 中使用 ngClick 触发函数
【发布时间】:2013-12-25 10:13:45
【问题描述】:

在使用 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

感谢您的帮助。

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-ng-repeat angularjs-ng-click transclusion


    【解决方案1】:

    我让 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”的指令定义的方法调用。我不知道这本身是否是最好的方法,但我已经在现有项目中使用它并取得了很好的效果;)

    【讨论】:

      【解决方案2】:

      你需要将函数传递给指令

      scope: {
         items: '=', 'myAlert': '='
      },
      

      【讨论】:

      【解决方案3】:

      指令模板中的 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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-22
        • 1970-01-01
        • 2019-01-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多