控制器必选指令不能找到 [英] Controller Required By Directive Can't Be Found

查看:98
本文介绍了控制器必选指令不能找到的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有,我想另一个指令能在打电话指令。我一直在试图用指令的控制器来尝试实现这一目标。

指令人会坐在同一页上的指令两个,指令一会调用由指令二的控制​​器公开的方法:

指令1:

 使用严格的;
angular.module('angularTestApp')
    .directive('fileLibrary',函数(){
        返回{
            templateUrl:查看/管理/ file_library /文件library.html',
            要求:'videoClipDetails',
            限制:AE,
            链接:功能postLink(范围,元素,ATTRS,videClipDetailsCtrl){
                scope.doSomethingInVideoClipDirective =功能(){
                    videClipDetailsCtrl.doSomething();
                }
            }
        };
    });

指令二:

 使用严格的;
angular.module('angularTestApp')
    .directive('videoClipDetails',函数(){
        返回{
            templateUrl:意见/ video_clip /视频剪辑details.html',
            限制:AE,
            控制器:函数($范围,$元素){
                this.doSomething =功能(){
                    的console.log(我做了一件');
                }
            },
            链接:功能postLink(范围,元素,ATTRS){
                的console.log('videoClipDetails指令');
                //启动的元素出来为隐藏
            }
        };
    });

文件,其中两个的使用和设置为兄弟姐妹:

 < D​​IV>
    < D​​IV视频剪辑的细节>< / DIV>
    <! - 该文件库主要成分 - >
    < D​​IV文件库>< / DIV>
< / DIV>

我知道阅读文档,我拿起该控制器可以当指令是相同的元素,这让我觉得我可能会寻找这个问题的错误的方式上进行共享。任何人都可以把我在正确的轨道上?


解决方案

从上指令 <的angular.js 文档/ p>


  

当一个指令使用要求 $编译除非指定控制器发现将抛出一个错误。在 ^ preFIX意味着其父母控制这个指令搜索(不包括 ^ preFIX,该指令看起来只是自己的元素上的控制器)。


所以基本上你正在尝试与有兄弟姐妹直接沟通是不可能的事情。我曾遇到同样的问题,但我不希望使用的服务进行通信。我想出了用父母的指令来管理它的孩子,这是兄弟姐妹之间的通信的方法。我张贴在github 的例子。

什么情况是,两个孩子需要父母(要求:^ parentDirective)和自己的控制器,这两者都传递到链接功能。从那里,每个孩子能到父控制器和所有的公共方法的参考,为各种各样的API。

下面是一个孩子的itemEditor

 函数的itemEditor(){
    var命令= {
        链接:链接,
        范围: {},
        控制器:控制器,
        controllerAs:虚拟机,
        要求:['^ itemManager','的itemEditor'],
        templateUrl:应用程序/脚本/ itemManager / itemManager.directives.itemEditor.html',
        限制:'A'
    };    返回指令;    功能链接(范围,元素,ATTRS,控制器){
        变种itemManagerController =控制器[0];
        变种itemEditorController =控制器[1];        itemEditorController.itemManager = itemManagerController;        itemEditorController.initialize();
    }    功能控制器(){
        VAR VM =这一点;        //属性
        vm.itemManager = {};
        vm.item = {ID:-1,名称:大小};        // 方法
        vm.initialize =初始化;
        vm.updateItem =的updateItem;
        vm.editItem = editItem;        // 功能
        函数初始化(){
            vm.itemManager.respondToEditsWith(vm.editItem);
        }        功能的updateItem(){
            vm.itemManager.updateItem(vm.item);
            vm.item = {};
        }        功能editItem(项目){
            vm.item.id = item.id;
            vm.item.name = item.name;
            vm.item.size = item.size;
        }
    }
}

请注意是如何传递到的值需要数组是父母指令的名称和当前指令的名字。这些都是然后在链接通过控制器的功能参数都可以访问。分配父指令的控制器作为当前孩子的财产,那么就可以对孩子的控制功能,通过在该属性来访问。

还要注意如何在孩子指令的链接的功能,我称之为从孩子的控制器中的初始化功能。这是其中的通信线路的一部分被建立

我基本上说,任何时候你(家长指导)接收请求编辑项目,使用一个名为雷 editItem 的这种方法,需要一个项目作为参数。<​​/ p>

下面是父指令

 函数itemManager(){
    var命令= {
        链接:链接,
        控制器:控制器,
        controllerAs:虚拟机,
        templateUrl:应用程序/脚本/ itemManager / itemManager.directives.itemManager.html',
        限制:'A'
    };    返回指令;    功能链路(范围,元件,ATTRS,控制器){    }    功能控制器(){
        VAR VM =这一点;        vm.updateMethod = NULL;
        vm.editMethod = NULL;        vm.updateItem =的updateItem;
        vm.editItem = editItem;
        vm.respondToUpdatesWith = respondToUpdatesWith;
        vm.respondToEditsWith = respondToEditsWith;        功能的updateItem(项目){
            vm.updateMethod(项目);
        }        功能editItem(项目){
            vm.editMethod(项目);
        }        功能respondToUpdatesWith(方法){
            vm.updateMethod =方法;
        }        功能respondToEditsWith(方法){
            vm.editMethod =方法;
        }
    }
}

在这里的家长,您可以看到 respondToEditsWith 采用的方法作为参数和值分配给它的 editMethod 属性。此属性被称为每当控制器的 editItem 方法被调用和项目对象传递给它,从而调用孩子指令的 editItem 方法。同样,数据保存工作在反向相同的方式。

更新:顺便问一下,这里是 $上一篇博客文章C $ crwall.com 这里也有我原来的想法与> ,并在指令控制器选项。这就是说,他建议在该职位的最后一个例子语法没有工作对我来说,这就是为什么我创造了我上面引用的例子。

I have a directive that I'd like another directive to be able to call in to. I have been trying to use directive controllers to try to achieve this.

Directive one would be sitting on the same page as directive two, and directive one would call methods exposed by directive two's controller:

Directive 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();
                }
            }
        };
    });

Directive Two:

'use strict';
angular.module('angularTestApp')
    .directive('videoClipDetails', function () {
        return {
            templateUrl: 'views/video_clip/video-clip-details.html',
            restrict: 'AE',
            controller: function($scope, $element) {
                this.doSomething = function() {
                    console.log('I did something');
                }
            },
            link: function postLink(scope, element, attrs) {
                console.log('videoClipDetails directive');
                //start the element out as hidden
            }
        };
    });

File where the two are used and set up as siblings:

<div>
    <div video-clip-details></div>
    <!-- main component for the file library -->
    <div file-library></div>
</div>

I know reading documentation I picked up that the controllers can be shared when the directives are on the same element, which makes me think I might be looking at this problem the wrong way. Can anyone put me on the right track?

解决方案

From the angular.js documentation on directives

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).

So basically what you are trying to do with having siblings directly communicate is not possible. I had run into this same issue but I did not want to use a service for communication. What I came up with was a method of using a parent directive to manage communication between its children, which are siblings. I posted the example on github.

What happens is that both children require the parent (require: '^parentDirective') and their own controller, both of which are passed into the link function. From there each child can get a reference to the parent controller and all of its public methods, as an API of sorts.

Below is one of the children 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, element, attrs, 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;
        }
    }
}

Note how the values passed into the require array are the parent directive's name and the current directive's name. These are then both accessible in the link function via the controllers parameter. Assign the parent directive's controller as a property of the current child's and then it can be accessed within the child's controller functions via that property.

Also notice how in the child directive's link function I call an initialize function from the child's controller. This is where part of the communication lines are established.

I'm basically saying, anytime you (parent directive) receive a request to edit an item, use this method of mine named editItem which takes an item as a parameter.

Here is the parent directive

function itemManager() {
    var directive = {
        link: link,
        controller: controller,
        controllerAs: 'vm',
        templateUrl: 'app/scripts/itemManager/itemManager.directives.itemManager.html',
        restrict: 'A'
    };

    return directive;

    function link(scope, element, attrs, 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;
        }
    }
}

Here in the parent you can see that the respondToEditsWith takes a method as a parameter and assigns that value to its editMethod property. This property is called whenever the controller's editItem method is called and the item object is passed on to it, thus calling the child directive's editItem method. Likewise, saving data works the same way in reverse.

Update: By the way, here is a blog post on coderwall.com where I got the original idea with good examples of require and controller options in directives. That said, his recommended syntax for the last example in that post did not work for me, which is why I created the example I reference above.

这篇关于控制器必选指令不能找到的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆