注入控制器到正在运行的应用程序角 [英] Inject a controller into a running Angular app

查看:112
本文介绍了注入控制器到正在运行的应用程序角的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经写了一些简单的code,以便引导情态动词与角在单击时加载链接到一个模式工作。现在所讨论的链路具有被包括在它们的源自己的角控制器。当模式被加载我第一次使用jQuery加载所有它的依赖脚本,然后有角编译模式,以便它是它的感知。然而似乎尽管我定义点播控制器的模式被加载,角不会成为它的知道,并抛出一个错误(未捕获的错误:参数'ControllerName不是一个函数,得到了未定义)

有没有我告诉角度来识别新控制器我已经在运行时添加的方式?

这里的模式code我使用FWIW(原型code):

  VAR directivesModule = angular.module('modal.directives',[]);
directivesModule.directive(模式功能(ModalService){
    返回函数($范围,ELEM,ATTRS){
            elem.on(点击,功能(E){
                亦即preventDefault();
                VAR URL = $(本).attr('href属性);                ModalService.load(URL,$范围);
            });
    };
});VAR servicesModule = angular.module('modal.service',[]);
servicesModule.factory('ModalService',函数($ HTTP,$编译,$ rootScope)
{
    变种ModalService = {};    ModalService.load =功能(URL,范围)
    {
        如果($('模式[ID ='+ URL +']')长方式> 0)
        {
            ModalService.show($('模式[ID ='+ URL +']'),范围);
            返回;
        }        $ http.get(URL).success(功能(数据){
            变种_data = $(数据);
            如果(_data.find(模体)。长度== 0){
                VAR _data = $('< D​​IV CLASS =模头>'
                      +'<按钮式=按钮级=关闭数据解雇=莫代尔ARIA隐藏=真> X< /按钮>'
                      +'< H3>'+ _ data.find(title.hidden)文本()+'< / H3和GT;< / DIV>'。
                      +'< D​​IV CLASS =模体>'+数据+'< / DIV>'
                      +'< D​​IV CLASS =模式躯>'
                      +'<按钮类=BTN BTN-接近>关闭< /按钮>< / DIV>');
            }            变种_scripts = [];
            VAR脚本= _data.find(脚本);
            如果(scripts.length大于0)
            {
                scripts.each(函数()
                {
                    VAR ELEM = $(本);
                    如果(elem.attr(SRC))
                    {
                        _scripts.push(elem.attr(SRC));
                        elem.remove();
                    }
                });
            }            ModalService.elem = $('< D​​IV CLASS =模式隐藏变脸ID ='+ URL +'>');
            ModalService.elem.append(_data);
            ModalService.elem.appendTo(身体);            如果(scripts.length大于0)
            {
                $ .getScript(_scripts,ModalService.show.bind(这一点,ModalService.elem,范围));
            }
            其他
            {
                ModalService.show(ModalService.elem,范围);
            }
        });
    };    ModalService.show =功能(ELEM,范围)
    {
        $ rootScope $广播('$ routeChangeSuccess')。        $编译(ELEM)(范围);
        elem.modal();        elem.find(BTN-关闭)。点击(函数(){
            elem.modal(隐藏);
            的setTimeout(函数(){elem.remove();},500);
        });
    };    返回ModalService;
});


解决方案

是的,这是可能的,所有需要的实用工具已经包含在角。我不会写准备code,但这里的东西,会给你一个想法:


  1. 装入HTML code,可能直接进入DOM - 像 $('#myDiv')负载('dialog.html')。不要绑定 NG-控制器控制器!保存到DOM节点的引用(姑且称之为元素)。


  2. 加载您的控制器 - 可能与 head.js 或什么最适合你的情况。保存到控制器功能(控制器是一个很好的名字)的引用。你不需要在你的角度应用注册,只是一个普通的,全球性的功能。引用任何所需的服务范围,并像往常一样:


 函数MyCtrl($范围,$资源,$ HTTP,$什么,YourOwnService){
    $ scope.hello =世界;
}


  1. 电线事情:

 函数($编译,$ rootScope,$注射){
    VAR元= angular.element('#myDiv'),
        控制器= MyCtrl;    //我们需要新的范围:
    变量$范围= $ rootScope $新的(真正的)。    //编译我们加载DOM片段并将其绑定到范围:
    $编译(元)($范围内);    $ inject.invoke(控制器,{
        $范围:$范围//你可以添加你的控制器所需的任何其他当地人
    });
}

我不能保证这个code的工作原理是,但它描述的技术,我几个星期前使用。但我必须提醒你,这会不会让你动态地添加AngularJS依赖关系:你的应用程序应该包括引导程序前加入所有可能的模块

I've written some simple code to allow for bootstrap modals to work with angular in that it loads a link into a modal when clicked. Now the links in question have their own angular controllers which are included in their source. When the modal is being loaded I first use jquery to load all it's dependant scripts and then have Angular compile the modal so that it is "aware" of it. However it seems that despite the fact that I define the controller on-demand as the modal is loaded, Angular will not be "aware" of it and throws an error (Uncaught Error: Argument 'ControllerName' is not a function, got undefined).

Is there a way for me to tell Angular to recognize the new controller I've added at run-time?

Here's the modal code I'm using fwiw (prototype code):

var directivesModule = angular.module('modal.directives', []);
directivesModule.directive("modal", function(ModalService) {
    return function($scope, elem, attrs) {
            elem.on("click", function(e) {
                e.preventDefault();
                var url = $(this).attr('href');

                ModalService.load(url, $scope);
            });
    };
});

var servicesModule = angular.module('modal.service', []);
servicesModule.factory('ModalService', function ($http, $compile, $rootScope)
{
    var ModalService = {};

    ModalService.load = function(url, scope)
    {
        if ($('.modal[id="'+url+'"]').length > 0)
        {
            ModalService.show($('.modal[id="'+url+'"]'), scope);
            return;
        }

        $http.get(url).success(function (data) {
            var _data = $(data);
            if (_data.find(".modal-body").length == 0) {
                var _data =  $('<div class="modal-header">'
                      + '<button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>'
                      + '<h3>'+_data.find(".title.hidden").text()+'</h3></div>'
                      + '<div class="modal-body">'+data+'</div>'
                      + '<div class="modal-footer">'
                      + '<button class="btn btn-close">Close</button></div>');
            }

            var _scripts = [];
            var scripts = _data.find("script");
            if (scripts.length > 0)
            {
                scripts.each(function()
                {
                    var elem = $(this);
                    if (elem.attr("src"))
                    {
                        _scripts.push(elem.attr("src"));
                        elem.remove();
                    }
                });
            }

            ModalService.elem = $('<div class="modal hide fade" id="'+url+'">');
            ModalService.elem.append(_data);
            ModalService.elem.appendTo("body");

            if (scripts.length > 0)
            {
                $.getScript(_scripts, ModalService.show.bind(this, ModalService.elem, scope));
            }
            else
            {
                ModalService.show(ModalService.elem, scope);
            }
        });
    };

    ModalService.show = function(elem, scope)
    {
        $rootScope.$broadcast('$routeChangeSuccess');

        $compile(elem)(scope);
        elem.modal();

        elem.find(".btn-close").click(function() {
            elem.modal("hide");
            setTimeout(function() { elem.remove(); }, 500);
        });
    };

    return ModalService;
});

解决方案

Yes, it is possible, and all needed utilities are already included in angular. I cannot write ready code, but here is something that will give you an idea:

  1. Load your HTML code, probably right into DOM -- something like $('#myDiv').load('dialog.html'). Do not bind controllers with ng-controller! Save a reference to DOM node (let's call it element).

  2. Load your controller -- probably with head.js or whatever suits your situation best. Save a reference to controller function (controller is a good name). You don't need to register it in your angular app, just a plain, global function. Reference any required services and scope as usual:

function MyCtrl($scope, $resource, $http, $whatever, YourOwnService) {
    $scope.hello = 'world';
}

  1. Wire things up:

function ($compile, $rootScope, $inject) {
    var element = angular.element('#myDiv'),
        controller = MyCtrl;

    // We need new scope:
    var $scope = $rootScope.$new(true);

    // Compile our loaded DOM snippet and bind it to scope:
    $compile(element)($scope);

    $inject.invoke(controller, {
        $scope:$scope // you can add any other locals required by your controller
    });
}

I cannot guarantee this code works as is, but it describes technique I've used couple of weeks ago. But I must warn you that this will not allow you to dynamically add AngularJS dependencies: your app should include all possible modules added before bootstrapping app.

这篇关于注入控制器到正在运行的应用程序角的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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