Предполагая, что у вас есть
Build Action
на Resource
URI-PACK-FORMAT
В моем случае он все еще не показывался.
Clean & Rebuild
Не просто Build исправил его для меня!
Я нашел возможное решение, где мне не нужно знать о контроллере перед загрузкой:
// Make module Foo and store $controllerProvider in a global
var controllerProvider = null;
angular.module('Foo', [], function($controllerProvider) {
controllerProvider = $controllerProvider;
});
// Bootstrap Foo
angular.bootstrap($('body'), ['Foo']);
// .. time passes ..
// Load javascript file with Ctrl controller
angular.module('Foo').controller('Ctrl', function($scope, $rootScope) {
$scope.msg = "It works! rootScope is " + $rootScope.$id +
", should be " + $('body').scope().$id;
});
// Load html file with content that uses Ctrl controller
$('<div id="ctrl" ng-controller="Ctrl" ng-bind="msg">').appendTo('body');
// Register Ctrl controller manually
// If you can reference the controller function directly, just run:
// $controllerProvider.register(controllerName, controllerFunction);
// Note: I haven't found a way to get $controllerProvider at this stage
// so I keep a reference from when I ran my module config
function registerController(moduleName, controllerName) {
// Here I cannot get the controller function directly so I
// need to loop through the module's _invokeQueue to get it
var queue = angular.module(moduleName)._invokeQueue;
for(var i=0;i<queue.length;i++) {
var call = queue[i];
if(call[0] == "$controllerProvider" &&
call[1] == "register" &&
call[2][0] == controllerName) {
controllerProvider.register(controllerName, call[2][1]);
}
}
}
registerController("Foo", "Ctrl");
// compile the new element
$('body').injector().invoke(function($compile, $rootScope) {
$compile($('#ctrl'))($rootScope);
$rootScope.$apply();
});
Fiddle . Единственная проблема заключается в том, что вам нужно сохранить $controllerProvider
и использовать его в том месте, где он действительно не должен использоваться (после загрузки). Также нет простого способа получить функцию, используемую для определения контроллера, пока он не будет зарегистрирован, поэтому мне нужно пройти через модуль _invokeQueue
, который недокументирован.
UPDATE : Для регистрации директив и служб вместо $controllerProvider.register
просто используйте $compileProvider.directive
и $provide.factory
соответственно. Опять же, вам нужно сохранить ссылки на них в исходной конфигурации вашего модуля.
UDPATE 2: Вот скрипка , которая автоматически регистрирует все контроллеры / директивы / службы, загруженные без необходимости укажите их индивидуально.
Мне также нужно было добавить несколько представлений и связать их с контроллерами во время выполнения из javascript-функции вне контекста angularJs, поэтому вот что я придумал:
<div id="mController" ng-controller="mainController">
</div>
<div id="ee">
2nd controller's view should be rendred here
</div>
теперь вызывает функцию setCnt () будет вводить и компилировать html, и он будет связан со вторым контроллером:
var app = angular.module('app', []);
function setCnt() {
// Injecting the view's html
var e1 = angular.element(document.getElementById("ee"));
e1.html('<div ng-controller="ctl2">my name: {{name}}</div>');
// Compile controller 2 html
var mController = angular.element(document.getElementById("mController"));
mController.scope().activateView(e1);
}
app.controller("mainController", function($scope, $compile) {
$scope.name = "this is name 1";
$scope.activateView = function(ele) {
$compile(ele.contents())($scope);
$scope.$apply();
};
});
app.controller("ctl2", function($scope) {
$scope.name = "this is name 2";
});
вот пример, чтобы проверить это: http://refork.com/x4bc
надеюсь, что это поможет.
mController.scope()
– Chtiwi Malek
14 April 2016 в 10:26
'use strict';
var mainApp = angular.module('mainApp', [
'ui.router',
'ui.bootstrap',
'ui.grid',
'ui.grid.edit',
'ngAnimate',
'headerModule',
'galleryModule',
'appointmentsModule',
]);
(function(){
var App = {
setControllers: mainApp.controller(controllers),
config: config.config(),
factories: {
authFactory: factories.auth(),
signupFactory: factories.signup(),
someRequestFactory: factories.saveSomeRequest(),
},
controllers: {
LoginController: controllers.userLogin(),
SignupController: controllers.signup(),
WhateverController: controllers.doWhatever(),
},
directives: {
signup: directives.signup(), // add new user
openLogin: directives.openLogin(), // opens login window
closeModal: directives.modalClose(), // close modal window
ngFileSelect: directives.fileSelect(),
ngFileDropAvailable: directives.fileDropAvailable(),
ngFileDrop: directives.fileDrop()
},
services: {
$upload: services.uploadFiles(),
}
};
})();
Приведенный выше код является только примером.
Таким образом, вам не нужно помещать ng-controller="someController"
в любом месте страницы - вы только объявляете <body ng-app="mainApp">
Такая же структура может использоваться для каждого модуля или модулей внутри модулей
Я только что улучшил функцию, написанную Jussi-Kosunen, так что все вещи могут быть выполнены с помощью одного вызова.
function registerController(moduleName, controllerName, template, container) {
// Load html file with content that uses Ctrl controller
$(template).appendTo(container);
// Here I cannot get the controller function directly so I
// need to loop through the module's _invokeQueue to get it
var queue = angular.module(moduleName)._invokeQueue;
for(var i=0;i<queue.length;i++) {
var call = queue[i];
if(call[0] == "$controllerProvider" &&
call[1] == "register" &&
call[2][0] == controllerName) {
controllerProvider.register(controllerName, call[2][1]);
}
}
angular.injector(['ng', 'Foo']).invoke(function($compile, $rootScope) {
$compile($('#ctrl'+controllerName))($rootScope);
$rootScope.$apply();
});
}
Таким образом вы можете программно загрузить ваш шаблон из любого места и инстанцировать контроллеры, даже вложенные.
Вот рабочий пример загрузки контроллера внутри другого: http://plnkr.co/edit/x3G38bi7iqtXKSDE09pN
почему бы не использовать config и ui-router?
он загружается во время выполнения, и вам не нужно показывать свои контроллеры в html-коде
, например, что-то вроде следующего
var config = {
config: function(){
mainApp.config(function ($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise("/");
$stateProvider
.state('index',{
views:{
'main':{
controller: 'PublicController',
templateUrl: 'templates/public-index.html'
}
}
})
.state('public',{
url: '/',
parent: 'index',
views: {
'logo' : {templateUrl:'modules/header/views/logo.html'},
'title':{
controller: 'HeaderController',
templateUrl: 'modules/header/views/title.html'
},
'topmenu': {
controller: 'TopMenuController',
templateUrl: 'modules/header/views/topmenu.html'
},
'apartments': {
controller: 'FreeAptController',
templateUrl:'modules/free_apt/views/apartments.html'
},
'appointments': {
controller: 'AppointmentsController',
templateUrl:'modules/appointments/views/frm_appointments.html'
},
}
})
.state('inside',{
views:{
'main':{
controller: 'InsideController',
templateUrl: 'templates/inside-index.html'
},
},
resolve: {
factory:checkRouting
}
})
.state('logged', {
url:'/inside',
parent: 'inside',
views:{
'logo': {templateUrl: 'modules/inside/views/logo.html'},
'title':{templateUrl:'modules/inside/views/title.html'},
'topmenu': {
// controller: 'InsideTopMenuController',
templateUrl: 'modules/inside/views/topmenu.html'
},
'messages': {
controller: 'MessagesController',
templateUrl: 'modules/inside/modules/messages/views/initial-view-messages.html'
},
'requests': {
//controller: 'RequestsController',
//templateUrl: 'modules/inside/modules/requests/views/initial-view-requests.html'
},
}
})
});
},
};
Предлагаю взглянуть на библиотеку ocLazyLoad , которая регистрирует модули (или контроллеры, службы и т. д. на существующем модуле) во время выполнения, а также загружает их с помощью requireJs или другой такой библиотеки.
bootstrap () вызовет для вас компилятор AngularJS, как и ng-app.
// Make module Foo
angular.module('Foo', []);
// Make controller Ctrl in module Foo
angular.module('Foo').controller('Ctrl', function($scope) {
$scope.name = 'DeathCarrot' });
// Load an element that uses controller Ctrl
$('<div ng-controller="Ctrl">{{name}}</div>').appendTo('body');
// Bootstrap with Foo
angular.bootstrap($('body'), ['Foo']);
Fiddle .
DeathCarrot
в контроллер вместо жестко закодированного значения внутри контроллера?
– Dis Shishkov
11 December 2013 в 15:15
Это то, что я сделал, на самом деле 2 части, используя ng-контроллер с его определенной функцией, а затем $ controller service для создания динамического контроллера: -
Во-первых, HTML - нам нужен Static Контроллер, который будет создавать динамический контроллер ..
<div ng-controller='staticCtrl'>
<div ng-controller='dynamicCtrl'>
{{ dynamicStuff }}
</div>
</div>
Статический контроллер «staticCtrl» определяет элемент области с названием «dynamicCtrl», который вызывается для создания динамического контроллера. ng-controller принимает либо предопределенный контроллер по имени, либо просматривает текущую область действия для функции с тем же именем.
.controller('staticCtrl', ['$scope', '$controller', function($scope, $controller) {
$scope.dynamicCtrl = function() {
var fn = eval('(function ($scope, $rootScope) { alert("I am dynamic, my $scope.$id = " + $scope.$id + ", $rootScope.$id = " + $rootScope.$id); })');
return $controller(fn, { $scope: $scope.$new() }).constructor;
}
}])
Мы используем eval (), чтобы взять строку (наш динамический код, который может исходить из в любом месте), а затем службу $ controller, которая примет либо предопределенное имя контроллера (нормальный случай), либо конструктор функции, за которым следуют параметры конструктора (мы передаем новую область). Угловая впрыснет (как любой контроллер) в функцию, мы запрашивают только $ scope и $ rootScope выше.
.injector()
, называя ее неопределенной. Я использую angular1.2.23. Устарела ли она в новых версиях? – Aarmora 8 January 2015 в 03:02