我正在构建AngularJS指令。我希望该指令包装其中包含ng-click的其他内容。单击后,结果按钮不执行任何操作。这是我尝试过的代码的简化版本:
(HTML)
<div ng-app="someapp"> <div ng-controller="Ctrl1"> <h2>Example</h2> <my-dir data-x="1"> <button ng-click="refresh()" id="refresh1">Refresh</button> </my-dir> <my-dir data-x="2"> <button ng-click="refresh()" id="refresh2">Refresh</button> </my-dir> </div> </div>
(JavaScript)
var app = angular.module('someapp', []); app.controller('Ctrl1', function($scope){ }); app.directive('myDir', function(){ return { restrict: 'E', scope: {}, template: '<div><p>Directive contents:</p><div ng-transclude></div></div>', transclude: true, link: function(scope, element, attrs){ $scope.y = attrs.x+1; scope.refresh = function(){ console.log("Refresh Called, y = ", $scope.y); } } }; });
如何更改它,以便该按钮实际触发$ scope.refresh()函数?
额外说明:
我需要该指令的本地对象信息(单个控制器中可以有多个该指令),因此我创建了一个新作用域。
就像dcodesmith指出的那样,包含在内的ng- click将绑定到控制器的作用域,而不是指令的作用域。取决于您要执行的操作,您可能希望它是行为(由于被包含的内容不是指令的一部分,为什么要调用指令范围的方法?)。就个人而言,我将改为在控制器的作用域上声明该方法。
app.controller('Ctrl1', function($scope){ $scope.refresh = function() { console.log("Refresh called."); }; });
在这种情况下,即使其中没有任何内容,您的指令也 应 声明隔离范围。
更新:根据您的评论,为什么不只将按钮包括在指令模板中?在这种情况下,它将已经与正确的范围相关联。
如果在某些情况下您不需要刷新按钮,则可以通过指令作为属性将其作为选项公开:
<my-dir show-button='true'></my-dir> // directive scope scope: { showButton: '=' }
我用这种方法遇到的最大问题是使用“双向绑定”运算符(=)将“ true”和“ false”视为表达式。我只是不太喜欢那种感觉。
无论如何,希望这可以解决您的问题…再说一遍,我是说这甚至不知道您所实现的实际上是否是刷新按钮,但是如果是,我将花一分钟时间考虑您是否真正需要一个“刷新”按钮。Angular擅长消除刷新按钮!
更新2:
我创建了一个plunkr,它显示了我认为我将如何处理您的情况,尤其是在重复使用任何其他控件的情况下:
http://plnkr.co/edit/FhrSwcrSZScvCfhtCSjn
在此示例中,两个按钮指令实际上是“ videoPlayer”指令的子代。它们的逻辑包含在该指令中,但是它们是分别实例化的,并且对于父指令而言不是必需的。“父母指令”(videplayer)只是公开了供“孩子”使用的API。同样不是说父方法是构造函数的方法,而不是作用域的方法。我认为这很奇怪,但这完全取自有角度的文档:
http://docs.angularjs.org/guide/directive(页面上的最后一个示例)
请注意,每个videoPlayer指令仍将具有其自己的隔离范围。