gpt4 book ai didi

javascript - 替代 angular.element(document).ready

转载 作者:行者123 更新时间:2023-11-30 09:33:54 26 4
gpt4 key购买 nike

我注意到与这个主题相关的大多数问题都是关于 jQuery $(document).ready 函数的替代方法,它是 angular.element($ document).ready 但是我想要一个可测试/最佳实践的替代方案。

我目前正在注入(inject) Bing map ,它需要在执行我的 Controller 中的代码之前加载。

目前我将 Controller 代码包装在准备好的文档中:

angular.element($document).ready(function() {
self.map = new Microsoft.Maps.Map(document.getElementById('map'), {
credentials: $scope.credentials,
enableClickableLogo: false,
enableSearchLogo: false,
showDashboard: false,
disableBirdseye: true,
allowInfoboxOverflow: true,
liteMode: true,
minZoom: 2
});

$scope.$watch('zoom', function (zoom) {
self.map.setView({animate: true, zoom: zoom});
});

if ($scope.onMapReady) {
$scope.onMapReady({ map: self.map });
}

});

哪个有效,但我无法测试它,所以我认为这是不正确的用法。我尝试在 $scope.loaded = true; 的指令中设置一个变量,因为我读到如果命中指令链接函数,则必须加载 DOM。然后我尝试用以下内容替换准备就绪的文档:

$scope.$watch('loaded', function () {
self.map = new Microsoft.Maps.Map(document.getElementById('map'), {
credentials: $scope.credentials,
enableClickableLogo: false,
enableSearchLogo: false,
showDashboard: false,
disableBirdseye: true,
allowInfoboxOverflow: true,
liteMode: true,
minZoom: 2
});

if ($scope.onMapReady) {
$scope.onMapReady({ map: self.map });
}
});

$scope.$watch('zoom', function (zoom) {
self.map.setView({animate: true, zoom: zoom});
});

“已加载” watch 按预期工作,但自然会在加载时缩放,那是在设置 map 之前。我觉得我可以将准备好的文档更改为 $timeout 函数,但这似乎是一种解决方法而不是正确的解决方案,是否有替代 angular.element($document ).ready 以相同的方式工作但允许我成功测试它的内容?

最佳答案

通常 Angular 应用程序已经在文档 ready 上启动了.这是使用 ng-app 自动引导的默认行为, 和手动引导 angular.bootstrap应该在 ready 上执行

该问题特定于当前案例(Microsoft 的 Bing Maps API)。考虑到 ready is suggested by Microsoft ,开发人员可以自己找到更好的选择。

<script src="https://www.bing.com/api/maps/mapcontrol"></script>

是同步加载的,但它会触发一些依赖项来加载,这些依赖项在初始文档 ready 时尚未加载。被触发。实际上,它需要 ready在另一个里面 ready为了完成初始化,这正是原始代码和微软示例所展示的,看起来不太好。

为了避免竞争条件,应用程序 Bootstrap 可以推迟到加载所有先决条件的那一刻,即 window load event instead of document ready .它可能会提供相当大的延迟,但它可以保证加载应用程序所依赖的脚本,而不管它们的传输是如何执行的:

angular.element(window).on('load', () => {
angular.bootstrap(document.body, ['app']
});

API 提供的控制初始化过程的替代方法是global callback function :

<script src="https://www.bing.com/api/maps/mapcontrol?callback=globalCallbackName"></script>

回调可以与服务打包在一起,而不是依赖于 <script> :

angular.module('bingMaps', [])
.factory('bingMapsLoader', ($q, $window, $document, $timeout) => {
var script = document.createElement('script');
script.src = 'https://www.bing.com/api/maps/mapcontrol?callback=bingMapsCallback';
script.async = true;

$document.find('body').append(script);

return $q((resolve, reject) => {
$window.bingMapsCallback = resolve;
$timeout(reject, 30000);
});
});

bingMapsLoader可以链接 promise 以保证 API 已初始化、放入路由器解析器等。

此外, Controller 构造函数在编译指令之前执行。无论是否使用第三方 API,将所有特定于 DOM 的代码移动到 Angular 1.4 及更低版本中的前/后链接函数和 Controller 都是正确的 $onInit$postLink在 Angular 1.5 或更高版本中 Hook :

app.controller('FooController', function (bingMapsLoader) {
this.$postLink = () => {
bingMapsLoader.then(() => this.mapsInit());
};

this.mapsInit = () => {
Microsoft.Maps.Map(...);
};
...

关于javascript - 替代 angular.element(document).ready,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44674270/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com