指令一将与指令二坐在同一页面上,指令一可以调用指令二的控制器暴露的方法:
指令1:
'use strict'; angular.module('angularTestApp') .directive('fileLibrary',function () { return { templateUrl: 'views/manage/file_library/file-library.html',require: 'videoClipDetails',restrict: 'AE',link: function postLink(scope,element,attrs,videClipDetailsCtrl) { scope.doSomethingInVideoClipDirective = function() { videClipDetailsCtrl.doSomething(); } } }; });
指令二:
'use strict'; angular.module('angularTestApp') .directive('videoClipDetails',function () { return { templateUrl: 'views/video_clip/video-clip-details.html',controller: function($scope,$element) { this.doSomething = function() { console.log('I did something'); } },attrs) { console.log('videoClipDetails directive'); //start the element out as hidden } }; });
使用两个文件并将其设置为兄弟姐妹:
<div> <div video-clip-details></div> <!-- main component for the file library --> <div file-library></div> </div>
我知道阅读文档,我拿起控制器可以共享,当指令在同一个元素,这使我认为我可能正在看这个问题的错误的方式。任何人都可以把我放在正确的轨道上吗?
When a directive uses
require
,$compile
will throw an error unless the specified controller is found. The^
prefix means that this directive searches for the controller on its parents (without the^
prefix,the directive would look for the controller on just its own element).
所以基本上你正在尝试与兄弟姐妹直接沟通是不可能的。我遇到了同样的问题,但是我不想使用一个服务进行通信。我想出的是一种使用父指令来管理其兄弟姐妹之间的通信的方法。我贴了the example on github。
会发生什么是两个孩子都要求父进程(require:’^ parentDirective’)和他们自己的控制器,这两个都被传入链接函数。从那里,每个孩子都可以获得对父控制器及其所有公共方法的引用,作为一种API。
下面是一个孩子的itemEditor
function itemEditor() { var directive = { link: link,scope: {},controller: controller,controllerAs: 'vm',require: ['^itemManager','itemEditor'],templateUrl: 'app/scripts/itemManager/itemManager.directives.itemEditor.html',restrict: 'A' }; return directive; function link(scope,controllers) { var itemManagerController = controllers[0]; var itemEditorController = controllers[1]; itemEditorController.itemManager = itemManagerController; itemEditorController.initialize(); } function controller() { var vm = this; // Properties vm.itemManager = {}; vm.item = { id: -1,name: "",size: "" }; // Methods vm.initialize = initialize; vm.updateItem = updateItem; vm.editItem = editItem; // Functions function initialize() { vm.itemManager.respondToEditsWith(vm.editItem); } function updateItem() { vm.itemManager.updateItem(vm.item); vm.item = {}; } function editItem(item) { vm.item.id = item.id; vm.item.name = item.name; vm.item.size = item.size; } } }
请注意,传递到require数组的值是parent指令的名称和当前的指令的名称。这些都可以通过控制器参数在链接功能中访问。将父指令的控制器指定为当前子级的属性,然后可以通过该属性在子控制器函数内访问。
还要注意如何在子代码的链接函数中调用子控件的初始化函数。这是建立通信线路的一部分。
我基本上说,任何时候你(父指令)收到一个编辑项目的请求,使用我的这个名为editItem的方法,它将一个项目作为一个参数。
这是父指令
function itemManager() { var directive = { link: link,templateUrl: 'app/scripts/itemManager/itemManager.directives.itemManager.html',controller) { } function controller() { var vm = this; vm.updateMethod = null; vm.editMethod = null; vm.updateItem = updateItem; vm.editItem = editItem; vm.respondToUpdatesWith = respondToUpdatesWith; vm.respondToEditsWith = respondToEditsWith; function updateItem(item) { vm.updateMethod(item); } function editItem(item) { vm.editMethod(item); } function respondToUpdatesWith(method) { vm.updateMethod = method; } function respondToEditsWith(method) { vm.editMethod = method; } } }
在父级中,您可以看到respondToEdits将一个方法作为参数,并将该值分配给其editMethod属性。每当调用控件的editItem方法并将项目对象传递给它时,调用该属性,从而调用子对象的editItem方法。同样,保存数据的工作原理与此相反。
更新:顺便说一下,这里是a blog post on coderwall.com,在那里我得到了最初的想法与指令中需要和控制器选项的很好的例子。也就是说,他对该帖子最后一个例子的推荐语法对我来说不起作用,这就是为什么我创建了上面我参考的例子。