本文翻译自:How to call a method defined in an AngularJS directive?

I have a directive, here is the code : 我有一个指令,这里是代码:

.directive('map', function() {return {restrict: 'E',replace: true,template: '<div></div>',link: function($scope, element, attrs) {var center = new google.maps.LatLng(50.1, 14.4); $scope.map_options = {zoom: 14,center: center,mapTypeId: google.maps.MapTypeId.ROADMAP};// create mapvar map = new google.maps.Map(document.getElementById(attrs.id), $scope.map_options);var dirService= new google.maps.DirectionsService();var dirRenderer= new google.maps.DirectionsRenderer()var showDirections = function(dirResult, dirStatus) {if (dirStatus != google.maps.DirectionsStatus.OK) {alert('Directions failed: ' + dirStatus);return;}// Show directionsdirRenderer.setMap(map);//$scope.dirRenderer.setPanel(Demo.dirContainer);dirRenderer.setDirections(dirResult);};// Watchvar updateMap = function(){dirService.route($scope.dirRequest, showDirections); };    $scope.$watch('dirRequest.origin', updateMap);google.maps.event.addListener(map, 'zoom_changed', function() {$scope.map_options.zoom = map.getZoom();});dirService.route($scope.dirRequest, showDirections);  }}
})

I would like to call updateMap() on a user action. 我想在用户操作上调用updateMap() The action button is not on the directive. 操作按钮不在指令上。

What is the best way to call updateMap() from a controller? 从控制器调用updateMap()的最佳方法是什么?


#1楼

参考:https://stackoom.com/question/18pdu/如何调用AngularJS指令中定义的方法


#2楼

Assuming that the action button uses the same controller $scope as the directive, just define function updateMap on $scope inside the link function. 假设操作按钮使用与指令相同的控制器$scope ,只需在链接函数内的$scope上定义函数updateMap Your controller can then call that function when the action button is clicked. 然后,您的控制器可以在单击操作按钮时调用该功能。

<div ng-controller="MyCtrl"><map></map><button ng-click="updateMap()">call updateMap()</button>
</div>
app.directive('map', function() {return {restrict: 'E',replace: true,template: '<div></div>',link: function($scope, element, attrs) {$scope.updateMap = function() {alert('inside updateMap()');}}}
});

fiddle 小提琴


As per @FlorianF's comment, if the directive uses an isolated scope, things are more complicated. 根据@ FlorianF的评论,如果指令使用隔离范围,事情会更复杂。 Here's one way to make it work: add a set-fn attribute to the map directive which will register the directive function with the controller: 以下是使其工作的一种方法:向map指令添加set-fn属性,该指令将向控制器注册指令函数:

<map set-fn="setDirectiveFn(theDirFn)"></map>
<button ng-click="directiveFn()">call directive function</button>
scope: { setFn: '&' },
link: function(scope, element, attrs) {scope.updateMap = function() {alert('inside updateMap()');}scope.setFn({theDirFn: scope.updateMap});
}
function MyCtrl($scope) {$scope.setDirectiveFn = function(directiveFn) {$scope.directiveFn = directiveFn;};
}

fiddle 小提琴


#3楼

If you want to use isolated scopes you can pass a control object using bi-directional binding = of a variable from the controller scope. 如果要使用隔离作用域可以传递使用双向结合的控制对象=来自控制器范围的可变的。 You can also control also several instances of the same directive on a page with the same control object. 您还可以在具有相同控件对象的页面上控制同一指令的多个实例。

 angular.module('directiveControlDemo', []) .controller('MainCtrl', function($scope) { $scope.focusinControl = {}; }) .directive('focusin', function factory() { return { restrict: 'E', replace: true, template: '<div>A:{{internalControl}}</div>', scope: { control: '=' }, link: function(scope, element, attrs) { scope.internalControl = scope.control || {}; scope.internalControl.takenTablets = 0; scope.internalControl.takeTablet = function() { scope.internalControl.takenTablets += 1; } } }; }); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="directiveControlDemo"> <div ng-controller="MainCtrl"> <button ng-click="focusinControl.takeTablet()">Call directive function</button> <p> <b>In controller scope:</b> {{focusinControl}} </p> <p> <b>In directive scope:</b> <focusin control="focusinControl"></focusin> </p> <p> <b>Without control object:</b> <focusin></focusin> </p> </div> </div> 

#4楼

Building on Oliver's answer - you might not always need to access a directive's inner methods, and in those cases you probably don't want to have to create a blank object and add a control attr to the directive just to prevent it from throwing an error ( cannot set property 'takeTablet' of undefined ). 基于Oliver的回答 - 您可能并不总是需要访问指令的内部方法,在这些情况下,您可能不希望创建空白对象并向control指令添加control attr以防止它引发错误( cannot set property 'takeTablet' of undefined )。

You also might want to use the method in other places within the directive. 您还可能希望在指令中的其他位置使用该方法。

I would add a check to make sure scope.control exists, and set methods to it in a similar fashion to the revealing module pattern 我会添加一个检查以确保scope.control存在,并以与显示模块模式类似的方式设置方法

app.directive('focusin', function factory() {return {restrict: 'E',replace: true,template: '<div>A:{{control}}</div>',scope: {control: '='},link : function (scope, element, attrs) {var takenTablets = 0;var takeTablet = function() {takenTablets += 1;  }if (scope.control) {scope.control = {takeTablet: takeTablet};}}};
});

#5楼

You can specify a DOM attribute that can be used to allow the directive to define a function on the parent scope. 您可以指定一个DOM属性,该属性可用于允许指令在父作用域上定义函数。 The parent scope can then call this method like any other. 然后,父作用域可以像任何其他方法一样调用此方法。 Here's a plunker. 这是一个吸烟者。 And below is the relevant code. 以下是相关代码。

clearfn is an attribute on the directive element into which the parent scope can pass a scope property which the directive can then set to a function that accomplish's the desired behavior. clearfn是指令元素的一个属性,父作用域可以将一个scope属性传递到该属性,然后该指令可以设置为一个完成所需行为的函数。

<!DOCTYPE html>
<html ng-app="myapp"><head><script data-require="angular.js@*" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script><link rel="stylesheet" href="style.css" /><style>my-box{display:block;border:solid 1px #aaa;min-width:50px;min-height:50px;padding:.5em;margin:1em;outline:0px;box-shadow:inset 0px 0px .4em #aaa;}</style></head><body ng-controller="mycontroller"><h1>Call method on directive</h1><button ng-click="clear()">Clear</button><my-box clearfn="clear" contentEditable=true></my-box><script>var app = angular.module('myapp', []);app.controller('mycontroller', function($scope){});app.directive('myBox', function(){return {restrict: 'E',scope: {clearFn: '=clearfn'},template: '',link: function(scope, element, attrs){element.html('Hello World!');scope.clearFn = function(){element.html('');};}}});</script></body>
</html>

#6楼

Although it might be tempting to expose an object on the isolated scope of a directive to facilitate communicating with it, doing can lead to confusing "spaghetti" code, especially if you need to chain this communication through a couple levels (controller, to directive, to nested directive, etc.) 虽然在指令的隔离范围上公开一个对象以便于与它进行通信可能很诱人,但这样做可能会导致混乱的“意大利面条”代码,特别是如果你需要通过几个层次链接这个通信(控制器,指令,嵌套指令等)

We originally went down this path but after some more research found that it made more sense and resulted in both more maintainable and readable code to expose events and properties that a directive will use for communication via a service then using $watch on that service's properties in the directive or any other controls that would need to react to those changes for communication. 我们最初走的是这条路,但是经过一些研究后发现它更有意义,并且导致更易于维护和可读的代码暴露事件和属性,指令将通过服务用于通信,然后在该服务的属性中使用$ watch指令或任何其他需要对这些通信变更作出反应的控制。

This abstraction works very nicely with AngularJS's dependency injection framework as you can inject the service into any items that need to react to those events. 这种抽象与AngularJS的依赖注入框架非常吻合,因为您可以将服务注入需要对这些事件做出反应的任何项目。 If you look at the Angular.js file, you'll see that the directives in there also use services and $watch in this manner, they don't expose events over the isolated scope. 如果查看Angular.js文件,您会看到其中的指令也以这种方式使用services和$ watch,它们不会在隔离范围上公开事件。

Lastly, in the case that you need to communicate between directives that are dependent on one another, I would recommend sharing a controller between those directives as the means of communication. 最后,如果您需要在彼此依赖的指令之间进行通信,我建议在这些指令之间共享一个控制器作为通信手段。

AngularJS's Wiki for Best Practices also mentions this: AngularJS的最佳实践Wiki也提到了这一点:

Only use .$broadcast(), .$emit() and .$on() for atomic events Events that are relevant globally across the entire app (such as a user authenticating or the app closing). 仅对原子事件使用。$ broadcast(),. $ emit()和。$ on()在整个应用程序中全局相关的事件(例如用户身份验证或应用程序关闭)。 If you want events specific to modules, services or widgets you should consider Services, Directive Controllers, or 3rd Party Libs 如果您需要特定于模块,服务或小部件的事件,则应考虑服务,指令控制器或第三方库

  • $scope.$watch() should replace the need for events $ scope。$ watch()应该取代事件的需要
  • Injecting services and calling methods directly is also useful for direct communication 直接注入服务和调用方法对于直接通信也很有用
  • Directives are able to directly communicate with each other through directive-controllers 指令能够通过指令控制器直接相互通信

如何调用AngularJS指令中定义的方法?相关推荐

  1. 【Groovy】闭包 Closure ( 闭包调用 与 call 方法关联 | 接口中定义 call() 方法 | 类中定义 call() 方法 | 代码示例 )

    文章目录 总结 一.接口中定义 call() 方法 二.类中定义 call() 方法 三.完整代码示例 总结 在 实例对象后使用 " () " 括号符号 , 表示调用该实例对象的 ...

  2. 【转】angularjs指令中的compile与link函数详解

    这篇文章主要介绍了angularjs指令中的compile与link函数详解,本文同时诉大家complie,pre-link,post-link的用法与区别等内容,需要的朋友可以参考下 通常大家在使用 ...

  3. vue(ref父组件使用子组件中定义的方法)

    一.前言 二.主要内容 1.实现效果(其实可以直接在父组件中操作子组件的显示隐藏,但是这里通过在子组件定义自己的显示隐藏效果,让父组件调用,训练一下这种方式) 2.分析: (1)点击父组件的某一个li ...

  4. (1)定义一个Circle类,包含一个double型的radius属性代表圆的半径,一个 findArea()方法返回圆的面积。 (2)定义一个类PassObject,在类中定义一个方法printA

      (1)定义一个 Circle 类,包含一个 double 型的 radius 属性代表圆的半径,一个 findArea() 方法返回圆的面积. ( 2 )定义一个类 PassObject ,在类中 ...

  5. java 接口的访问权限_证明接口interface中定义的方法的访问权限为public

    如题,证明Java中接口文件中定义的方法访问权限为public. 众所周知,接口中的方法默认是public abstract 类型的,它必须由子类实现之.那怎么证明呢,反射. 定义接口文件 packa ...

  6. java定义常量_JAVA中定义常量方法

    JAVA中定义常量方法 (2013-01-28 14:30:19) 标签: it 一.常量定义的基本注意事项. 在Java语言中,主要是利用final关键字(在Java类中灵活使用Static关键字) ...

  7. js代码 父页面调用子页面中的js方法,子页面调用父页面中的js方法

    文中代码亲测可用,转载以示尊重!!! <!--主页面中的JS代码--> <script type="text/javascript"> //调用子页面的方法 ...

  8. angularjs指令中的compile与link函数详解

    通常大家在使用ng中的指令的时候,用的链接函数最多的是link属性,下面这篇文章将告诉大家complie,pre-link,post-link的用法与区别. angularjs里的指令非常神奇,允许你 ...

  9. AngularJS 指令中的require

    require参数可以被设置为字符串或数组,字符串代表另外一个指令的名字.require会将控制器注入到其值所指定的指令中,并作为当前指令的链接函数的第四个参数. 字符串或数组元素的值是会在当前指令的 ...

最新文章

  1. ipqc异常处理流程图_产线异常处理流程
  2. python有哪些常用的package_个人Python常用Package及其安装
  3. 资料员计算机知识大全,最新资料员专业基础知识
  4. Class Activation Mapping(CAM)类激活映射
  5. servlet api.jar是干什么的?
  6. Flutter 即学即用系列博客——09 MethodChannel 实现原生与 Flutter 通信(二)
  7. 同时买票是怎么实现的_搞笑GIF段子:这位挖掘机司机真的很牛,同时胆子很大...
  8. windows2008r2安装笔记
  9. matlab fir带通滤波,基于Matlab的FIR带通滤波器设计与实现
  10. 怎样进行文献调研?——与青年朋友谈科研(7)
  11. Java 菜鸟入门 | Java中的静态变量、实例变量、局部变量和成员变量
  12. Qt学习之自定义控件——颜色下拉框
  13. jQuery实现下拉菜单[代码+详细讲解+效果图]
  14. KiB、MiB与KB、MB的区别
  15. C++ 排列组合问题
  16. 什么是信念?信任?信仰?
  17. java使用jacob操作word文档
  18. 超级无敌小小迷你宝宝小可爱大仙女芊老婆~
  19. 放款2500亿仅占1%,度小满要做消费金融拉动内需的新动力?
  20. SAP idoc功能够强大: 采购订单下达自动触发销售订单创建

热门文章

  1. .NET3.5中的高性能 Socket API
  2. 将高级service开发简单化
  3. 获取ServerManager
  4. 内存分配策略(一):JVM栈桢及方法调用详解
  5. 看图说话:OpenGL模型矩阵和投影矩阵
  6. 【剑指offer-Java版】15链表中倒数第K个结点
  7. spring单元测试
  8. python渐变颜色表_python – 具有固定颜色渐变的np.histogram2D
  9. 聚合Aggregation与合成Composition
  10. uniapp实现图片预览功能