[英]How can I execute a function in an angularJS controller from a backbone controller
I am working on a application originally created with backbone and jQuery, however due to client requirement, new modules are built with angular.我正在开发一个最初用主干和 jQuery 创建的应用程序,但是由于客户端的要求,新模块是用 angular 构建的。 Routing of the application is handled with backbone route and we have successfully integrated angular modules.
应用程序的路由是通过主干路由处理的,我们已经成功地集成了 angular 模块。
The actual problem is, I need to retrieve the current instance of a module in angular and execute a function from the controller of that module based on actions handled by a backbone controller.实际问题是,我需要以角度检索模块的当前实例,并根据主干控制器处理的操作从该模块的控制器执行函数。
Here is what my angular module and controller looks like:这是我的 angular 模块和控制器的样子:
//In chat.module.js
( function () {
angular
.module( 'chat.module', [] );
})();
//In chat.controller.js
(function () {
angular
.module('chat.module')
.controller('chat.controller', ['profileFactory', '$filter', '$q', '$timeout', 'Position', 'Chat', chat]);
function chat(profileFactory, $filter, $q, $timeout, Position, Chat) {
var vm = this;
vm.initChatFlag = false;
vm.initChat = initChat;
vm.setInformation = setInformation;
function setInformation() {
//handle business logic here
}
...
In backbone, the module is created as follows:在主干中,模块创建如下:
chatmodule: function () {
var self = this;
var element = angular.element(document.querySelector('#modalCallback'));
var chat = angular.element(document.querySelector('#chatModule'));
var isInitializedChat = chat.injector();
var isInitialized = element.injector();
if (!isInitialized) {
angular.bootstrap($('#modalCallback'), ['app']);
}
if (!isInitializedChat) {
angular.bootstrap($('#chatModule'), ['app']);
}
//TODO: chat.controller.setInformation() get access to fields like chat.controller.initChatFlag etc
The main app module is defined thus:主应用模块定义如下:
(function(){
angular
.module('app',[
'callback',
'ui.bootstrap',
'720kb.datepicker',
'ngLocale',
'directives.module',
'interceptor',
'directive.loading',
'angularUtils.directives.dirPagination',
'blog.module',
'profile.module',
'filters.module',
'chat.module',
'ui.toggle',
]);
})();
The AngularJS $injector
is where a lot of the magic happens, so if you expose that outside of the AngularJS code you can hook it up to non-AngularJS code like the following: AngularJS
$injector
是很多魔法发生的地方,所以如果你将它暴露在 AngularJS 代码之外,你可以将它连接到非 AngularJS 代码,如下所示:
//A simple AngularJS service:
app.service('myService', function() {
this.message = "This is my default message.";
});
//Expose the injector outside the angular app.
app.run(function($injector, $window) {
$window.angularInjector = $injector;
});
//Then use the injector to get access to the service.
//Make sure to wrap the code in a `$apply()` so an
//AngularJS digest cycle will run
function nonAngularEventHandler() {
angularInjector.invoke(function(myService, $rootScope) {
$rootScope.$apply(function() {
myService.message = "Now this is my message."
});
});
}
Edit: Alternatively, simplify the call like so.编辑:或者,像这样简化调用。
//Instead of exposing the $injector directly, wrap it in a function
//which will do the $apply() for you.
app.run(function($injector, $window, $rootScope) {
$window.callInMyAngularApp = function(func) {
$rootScope.$apply(function() {
$injector.invoke(func);
});
}
});
//Then call that function with an injectable function like so.
function nonAngularClick() {
callInMyAngularApp(function(myService) {
myService.message = "Now this is my message."
});
}
//And remember if you're minifying, you'll want the minify-safe
//version of the injectable function like this
function nonAngularClick() {
callInMyAngularApp(['myService', function(myService) {
myService.message = "Now this is my message."
}]);
}
Update: (last one I promise!) The above will work fine, but you might want to consider exposing a well-defined API instead of a generic injectable interface.更新:(我保证最后一个!)上面的方法可以正常工作,但您可能需要考虑公开定义良好的 API 而不是通用的可注入接口。 Consider the following.
考虑以下问题。
//Now I have a limited API defined in a service
app.service("myExternalApi", function($rootScope, myService) {
this.changeMyMessage = function(message) {
$rootScope.$apply(function() {
myService.message = message;
});
};
});
//And I just expose that API
app.run(function($window, myExternalApi) {
$window.myExternalApi = myExternalApi;
});
//And the call from outside of angular is much cleaner.
function nonAngularClick() {
myExternalApi.changeMyMessage("Now this is my message.");
}
I was able to get access to the controller using answer from this post - https://stackoverflow.com/a/21997129/7411342我能够使用这篇文章的答案访问控制器 - https://stackoverflow.com/a/21997129/7411342
var Chat = angular.element(document.querySelector('#chatModule')).scope();
if(!Chat) return;
if(Chat.chatCtrl.initChatFlag) {
Chat.chatCtrl.setInformation();
}else{
console.log('Chat has not been initialized');
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.