Javascript 从第三方初始化触发

Javascript 从第三方初始化触发,javascript,angularjs,Javascript,Angularjs,我是angular的新手,使用简单的angular应用程序没有问题,但现在我想与第三方组件集成。我可以想出一些难题来实现我想做的事情,但我更愿意使用一个干净的解决方案来满足一般需求:如何从“外部”角度调用角度代码 我希望我的angular应用程序初始化启动视图,然后等待第三方软件初始化,然后让angular显示主视图。第三方软件通过各种异步调用进行初始化,可能需要一两秒钟,或者在极端情况下需要更长的时间。它提供了一个回调函数,当它准备好时将被调用 现在来模拟我得到的效果: .controller

我是angular的新手,使用简单的angular应用程序没有问题,但现在我想与第三方组件集成。我可以想出一些难题来实现我想做的事情,但我更愿意使用一个干净的解决方案来满足一般需求:如何从“外部”角度调用角度代码

我希望我的angular应用程序初始化启动视图,然后等待第三方软件初始化,然后让angular显示主视图。第三方软件通过各种异步调用进行初始化,可能需要一两秒钟,或者在极端情况下需要更长的时间。它提供了一个回调函数,当它准备好时将被调用

现在来模拟我得到的效果:

.controller('MySplash', ['$scope', '$location', '$q', 
                             function($scope, $location, $q) {   

      $scope.waitForInit = $q.defer();

      $scope.waitForInit.promise.then(function() {
          $location.path('/tab/MyMainView');
      });

      $scope.waitForInit.resolve();  // fake the post-init triggering
    }])
因此,这显示启动屏幕,当延迟满足时显示主屏幕,在这种情况下,当然会立即发生

我还有一个由第三方软件提供的功能

 CalledWhenThirdPartyReady() {
      // put some code here
 }
从概念上讲,我想做的就是将resolve调用移到这个回调中

 CalledWhenThirdPartyReady() {
       $scope.waitForInit.resolve();
 }
从根本上说,我的难题是如何让一些有效的独立代码访问DI。在概念上,我只想调用一个角度服务,或者访问一个角度变量。我试过这种方法

 CalledWhenThirdPartyReady() {

      angular.module('myApp')

   .run(["$rootScope", "$location",
              function ($rootScope, $location) {
                // just to show access to DI-ed variables
                console.log("Run in module", $rootScope, ",", $location);

            }] );
 }

考虑到run方法将被调用,并且我可以访问注入的变量,但run从未被触发,我猜是因为我注册run()太晚了。

尝试使用
$apply

$apply()用于从外部以角度执行表达式 角度框架。(例如,从浏览器DOM事件, setTimeout、XHR或第三方库)。因为我们正在召唤 我们需要的角度框架执行适当的生命周期范围 异常处理,执行监视

例如:

CalledWhenThirdPartyReady() {
    $scope.$apply($scope.waitForInit.resolve());  
}
这要求在第三方就绪时调用的
可以访问
$scope
,例如,如果它是在
控制器中定义的。如果需要在Angular应用程序之外定义第三方已调用的
,则需要以其他方式进行处理

从外部调用
控制器中的函数的示例:

JS:

Html:


window.onload=函数(){
console.log(“加载”);
setTimeout(函数(){
var controllerScope=angular.element(document.querySelector('body')).scope();
controllerScope.resolve();
}, 1000);
}

上面tasseKATT给出的链接给出了外部交互的一般原则,特别是通过DOM查找角度入口点

最后,我采取了向模块添加属性的方法,有效地将模块用作草稿行,以便在我的应用程序的各个部分之间进行通信。(我想比使用全局搜索略好一些。)

在我的控制器模块中:

angular.module('starter.controllers', [])


.controller('PetSplashCtrl', ['$scope', '$location', '$q', 
                         function($scope, $location, $q) {   

  var initDeferred = $q.defer();
  angular.module('starter.controllers').initDeferred = initDeferred;

  initDeferred.promise.then(function() {
      $location.path('/tab/pets');
  });

}]);
并在第三方回调中添加

angular.module('starter.controllers').initDeferred.resolve();
angular和第三方代码之间存在竞争条件,因此我需要在调用resolve()之前检查angular是否已准备就绪,以及承诺是否已设置:


我不确定通过DOM查找服务是否比这更好。

谢谢,从概念上讲,这正是我想要做的。问题是我似乎无法访问变量$scope。我已经尝试了您的代码,$scope不是已知变量。在我有限的理解中,我希望需要注入它,但我不知道如何在“外部”代码中这样做。你能移动被调用的HenthirdPartyReady()并从控制器内部调用第三方吗?不,这是问题所在。第三方代码是通过加载其JavaScript文件启动的,它承诺在初始化后回调全局CalledWhenThirdPartyReady()函数。所以我无法从“内部”角度进行控制。我明白了。我用另一个例子更新了我的答案。如果它不适合你的需要,请告诉我,我会尽力帮助你。例如,如果您没有将一个元素与ng控制器一起使用,我可以看到类似的东西是如何工作的。碰巧我没有使用ng控制器,只使用ng应用程序。我假设我可能可以做一些类似于您的代码的事情,我关心的是我们没有使用angular的API,我们是否有效地达到angular设置的数据结构的峰值?我会尝试一下,但是如果我想到任何使用API的东西,我会非常感激。
angular.module('starter.controllers', [])


.controller('PetSplashCtrl', ['$scope', '$location', '$q', 
                         function($scope, $location, $q) {   

  var initDeferred = $q.defer();
  angular.module('starter.controllers').initDeferred = initDeferred;

  initDeferred.promise.then(function() {
      $location.path('/tab/pets');
  });

}]);
angular.module('starter.controllers').initDeferred.resolve();
function thirdPartyCallback(){

var initWaiter = function(){

    if ( typeof angular !== 'undefined' 
              && angular.module('starter.controllers') 
              && angular.module('starter.controllers').initDeferred
       ){
        angular.module('starter.controllers').initDeferred.resolve();
        console.log("init done");

    } else {
        console.log("init wait");
        setTimeout(initWaiter, 1000);
    }               
};

initWaiter();

}