javascript - Inject a controller into a running Angular app -
i've written simple code allow bootstrap modals work angular in loads link modal when clicked. links in question have own angular controllers included in source. when modal being loaded first use jquery load it's dependant scripts , have angular compile modal "aware" of it. seems despite fact define controller on-demand modal loaded, angular not "aware" of , throws error (uncaught error: argument 'controllername' not function, got undefined).
is there way me tell angular recognize new controller i've added @ run-time?
here's 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, possible, , needed utilities included in angular. cannot write ready code, here give idea:
load html code, right dom --
$('#mydiv').load('dialog.html')
. not bind controllersng-controller
! save reference dom node (let's callelement
).load controller -- head.js or whatever suits situation best. save reference controller function (
controller
name). don't need register in angular app, plain, global function. reference required services , scope usual:
function myctrl($scope, $resource, $http, $whatever, yourownservice) { $scope.hello = 'world'; }
- wire things up:
function ($compile, $rootscope, $inject) { var element = angular.element('#mydiv'), controller = myctrl; // need new scope: var $scope = $rootscope.$new(true); // compile our loaded dom snippet , bind scope: $compile(element)($scope); $inject.invoke(controller, { $scope:$scope // can add other locals required controller }); }
i cannot guarantee code works is, describes technique i've used couple of weeks ago. must warn not allow dynamically add angularjs dependencies: app should include possible modules added before bootstrapping app.
Comments
Post a Comment