【问题标题】:How to Initialize third party JavaScript asynchronous library before loading AngularJS如何在加载 AngularJS 之前初始化第三方 JavaScript 异步库
【发布时间】:2018-03-01 09:27:19
【问题描述】:

在 AngularJS 的 RUN 方法中初始化第三方 JavaScript API (iHUB) 时遇到问题。目前代码在异步模式下运行。我希望 IHUB 首先初始化,然后调用 AngularJS 路由/控制器。 (是否可以利用IHUB提供的回调方法?)

var nameApp = angular.module('nameApp', ['ngRoute']);

nameApp.run(['$window', 'myService', function($window, myService) {

   //initialize IHUB
   var actuate= new actuate();
   actuate.initialize('http://localhost:8700/iportal', settings.reqOps, "user", "pwd", callback);

   function callback(){
     alert('started!!');
   }

}]);

nameApp.config(['$routeProvider', function($routeProvider) {
  $routeProvider.
    when('/:tabname', {
      templateUrl: 'pages/analyticsDetail.html',
      controller: 'tabDetailCtrl'
    }).
    when('/:tabname/:reportName', {
      templateUrl: 'pages/analyticsDetail.html',
      controller: 'reportDetailCtrl'
    }).
    otherwise({
      redirectTo: '/Buy Side Dashboard'
    });
}]);

【问题讨论】:

  • 为此使用路由解析器。
  • angular.config 首先运行并在应用程序引导(启动)之前对其进行配置,angular.run 将在创建注入器时运行,因此在其他方法之后运行,因此它可以使用事件侦听器。 More about it。由于配置是针对提供者的,因此请尝试在其中初始化 (resolve / $provide)
  • 您是否尝试将文件首先包含在 angular.js 的 html 声明中?
  • 有什么反馈吗?

标签: javascript angularjs birt


【解决方案1】:

只有一种方法可以在 AngularJS 初始化行为之前使用angular.bootstrap(); 实现“真实”。这允许您手动初始化 AngularJS 应用程序。

注意:手动引导应用时不应使用 ng-app 指令。

> Fiddle demo

查看

<div ng-controller="MyController">
  Hello, {{greetMe}}!
</div>

应用

angular.module('myApp', [])
  .controller('MyController', ['$scope', function ($scope) {
    $scope.greetMe = 'World';
  }]);

var actuateDummy = {
  initialize: function (callback) {
    setTimeout(callback, 2500);
  }
};

actuateDummy.initialize(function () {
  angular.element(function() {
    angular.bootstrap(document, ['myApp']);
  });
})

这是使用resolve 状态ui-router 的另一种方法。此服务仅在尚未初始化时才初始化 iHUB

此服务还返回actuate 对象。通过这种方式,您可以在初始化后在控制器或组件中使用它。

> Demo fiddle

查看

<nav>
  <a ui-sref="state1">State 1</a>
  <a ui-sref="state2">State 2</a>
</nav>

<div ui-view></div>

AngularJS 应用程序

var myApp = angular.module("myApp", ["ui.router"]);

myApp.config(function($stateProvider, $urlRouterProvider) {
  $stateProvider.state("state1", {
    url: "#",
    template: "<p>State 1</p>",
    controller: "Ctrl1",
    resolve: {
      iHubInit: function(iHubService) {
        return iHubService.init()
      }
    }
  }).state("state2", {
    url: "#",
    template: "<p>State 2</p>",
    controller: "Ctrl2",
    resolve: {
      iHubInit: function(iHubService) {
        return iHubService.init()
      }
    }
  });
});

myApp.controller("Ctrl1", function($scope, iHubService) {
  console.log("Ctrl1 loaded.");
});

myApp.controller("Ctrl2", function($scope, iHubService) {
  console.log("Ctrl2 loaded.");
});

myApp.service('iHubService', ["$q", function($q) {

  this.iHubServiceInitialized = false;
  this.actuate = null;

  this.init = function() {

    if (!this.iHubServiceInitialized) {

      //Init
      var self = this;
      var deferred = $q.defer();
      this.actuate = new actuate();

      //initialize
      this.actuate.initialize('http://localhost:8700/iportal', settings.reqOps, "user", "pwd", function() {
        self.iHubServiceInitialized = true;
        deferred.resolve(self.actuate);
      });

      return deferred.promise;
    } else {
      return this.actuate;
    }
  }
}]);

【讨论】:

  • 您的第一个解决方案运行良好。但是,使用路由解析器,初始化会被多次调用。我认为 **iHubServiceInitialized ** 变量存在问题,每次调用服务时它都会重置为 false。
  • @Manu,不。 iHubServiceInitialized 未重置 -> 您可以在此处查看 jsfiddle.net/654qesvv。服务是一个对象,它以相同的状态注入到您要使用它的每个组件中。
  • 更正了服务代码。现在它工作正常。再次感谢您的帮助。
【解决方案2】:

在配置路由提供程序时尝试添加解析属性,如下所示:

var nameApp = angular.module('nameApp', ['ngRoute']);

nameApp.config(['$routeProvider', function($routeProvider) {
  $routeProvider.
    when('/:tabname', {
      templateUrl: 'pages/analyticsDetail.html',
      controller: 'tabDetailCtrl',
      resolve: {
                ihubInit: ['iHubService', function (iHubService) {
                    return iHubService.init();
                }]
            }
    }).
    when('/:tabname/:reportName', {
      templateUrl: 'pages/analyticsDetail.html',
      controller: 'reportDetailCtrl',
      resolve: {
                ihubInit: ['iHubService', function (iHubService) {
                    return iHubService.init();
                }]
            }
    }).
    otherwise({
      redirectTo: '/Buy Side Dashboard'
    });
}]);

nameApp.service('iHubService', ["$q", function($q){
  this.init = function() {
    var deferred = $q.defer();
    var actuate= new actuate();
    actuate.initialize('http://localhost:8700/iportal', settings.reqOps, "user", "pwd", callback);

    function callback(){
       deferred.resolve();
    }
    return deferred.promise;
  }
}]);

【讨论】:

  • 感谢您的帮助。但是,IHUB 初始化应该只调用一次(这就像登录到 iHub 服务器)。使用路由提供者,每次路由参数更改时都会初始化 ihub。
  • 好吧,只需添加一个布尔值initialized 并在 iHub 初始化时将其设置为 true,如果此布尔值为 true,则不要再次调用。但是@lin 的答案可能是一个不错的答案 ;-)
猜你喜欢
  • 1970-01-01
  • 2013-07-01
  • 2021-01-25
  • 1970-01-01
  • 2013-10-03
  • 1970-01-01
  • 2013-02-26
  • 1970-01-01
  • 2012-12-27
相关资源
最近更新 更多