Javascript 将控制器注入正在运行的Angular应用程序

Javascript 将控制器注入正在运行的Angular应用程序,javascript,angularjs,Javascript,Angularjs,我已经编写了一些简单的代码,允许引导模态与angular一起工作,因为它在单击时将链接加载到模态中。现在所讨论的链接有它们自己的角度控制器,这些控制器包含在它们的源中。当加载模式时,我首先使用jquery加载所有依赖于它的脚本,然后让Angular编译模式,以便它“意识到”它。然而,似乎尽管我在加载模态时定义了按需控制器,Angular不会“意识到”它并抛出错误(未捕获错误:参数“ControllerName”不是函数,未定义) 有没有办法让Angular识别我在运行时添加的新控制器 以下是我使

我已经编写了一些简单的代码,允许引导模态与angular一起工作,因为它在单击时将链接加载到模态中。现在所讨论的链接有它们自己的角度控制器,这些控制器包含在它们的源中。当加载模式时,我首先使用jquery加载所有依赖于它的脚本,然后让Angular编译模式,以便它“意识到”它。然而,似乎尽管我在加载模态时定义了按需控制器,Angular不会“意识到”它并抛出错误(未捕获错误:参数“ControllerName”不是函数,未定义)

有没有办法让Angular识别我在运行时添加的新控制器

以下是我使用的模式代码fwiw(原型代码):

var directivesModule=angular.module('modal.directives',[]);
directivesModule.directive(“模态”,函数(ModalService){
返回函数($scope、elem、attrs){
要素开启(“点击”,功能(e){
e、 预防默认值();
var url=$(this.attr('href');
加载(url,$scope);
});
};
});
var servicesModule=angular.module('modal.service',[]);
servicesModule.factory('ModalService',函数($http、$compile、$rootScope)
{
var ModalService={};
ModalService.load=函数(url,作用域)
{
如果($('.modal[id=“'+url+''“]')).length>0)
{
ModalService.show($('.modal[id=“'+url+'“]”),范围);
返回;
}
$http.get(url).success(函数(数据){
var_数据=$(数据);
if(_data.find(“.modal body”).length==0){
var_数据=$('')
+“x”
+“”+_data.find(“.title.hidden”).text()+“”
+''+数据+''
+ ''
+“关闭”);
}
var_脚本=[];
var scripts=_data.find(“脚本”);
如果(scripts.length>0)
{
脚本。每个(函数()
{
var elem=$(本);
if(要素属性(“src”))
{
_scripts.push(elem.attr(“src”);
elem.remove();
}
});
}
ModalService.elem=$('');
ModalService.elem.append(_data);
ModalService.elem.appendTo(“主体”);
如果(scripts.length>0)
{
$.getScript(_scripts,ModalService.show.bind(this,ModalService.elem,scope));
}
其他的
{
ModalService.show(ModalService.elem,scope);
}
});
};
ModalService.show=功能(元素,范围)
{
$rootScope.$broadcast(“$routeChangeSuccess”);
$compile(elem)(范围);
模态元素();
元素查找(“.btn关闭”)。单击(函数(){
模态元素(“隐藏”);
setTimeout(函数(){elem.remove();},500);
});
};
返回ModalService;
});

是的,这是可能的,所有需要的实用程序都已包含在angular中。我无法编写现成的代码,但这里有一些东西可以给您一个想法:

  • 加载HTML代码,可能直接加载到DOM中——类似于
    $('#myDiv')。加载('dialog.HTML')
    。不要将控制器与ng控制器绑定!保存对DOM节点的引用(我们称之为
    元素

  • 加载你的控制器——可能有或任何最适合你的情况。保存对控制器功能的引用(
    controller
    是个好名字)。你不需要在angular应用程序中注册它,只是一个普通的全局函数。照常参考任何要求的服务和范围:

  • 把事情联系起来:

  • 我不能保证这段代码按原样工作,但它描述了我几周前使用的技术。但我必须警告您,这将不允许您动态添加AngularJS依赖项:您的应用程序应该包括在引导应用程序之前添加的所有可能模块。

    建议您创建一个工作模式。不清楚您为什么需要额外的控制器谢谢-今天晚些时候我有时间时会这样做。简而言之,我想要一个模式,它使用通过ajax检索的内容,也通过ajax检索其控制器。
    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;
    });
    
    function MyCtrl($scope, $resource, $http, $whatever, YourOwnService) {
        $scope.hello = 'world';
    }
    
    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
        });
    }