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