如何从骨干控制器执行angularJS控制器中的功能

时间:2018-03-28 15:50:33

标签: javascript angularjs backbone.js

我正在开发一个最初使用backbone和jQuery创建的应用程序,但是由于客户端的要求,新模块是使用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 bussiness logic here
    }

    ...

在骨干网中,模块创建如下:

        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

因此定义了主app模块:

    (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',
        ]);
})();

2 个答案:

答案 0 :(得分:1)

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."
    });
  });
}

编辑:或者,像这样简化通话。

//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."
  }]);
}

更新:(最后一个我保证!) 上面的工作正常,但您可能需要考虑公开定义良好的API而不是通用的可注入接口。请考虑以下事项。

//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.");
}

答案 1 :(得分:0)

我可以使用此帖子的回答 - 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');
    }