用 Fetch API 替换 $http [英] Replacing $http with Fetch API

查看:39
本文介绍了用 Fetch API 替换 $http的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 Fetch API 替换 $http 并用 Promise API 替换 $q.正因为如此,Angular 不再运行摘要循环,因此 UI 没有呈现.为了解决这个问题,我尝试了 Zone.js,这似乎部分解决了我们的问题.不幸的是它的 API 在 0.6 中完全改变,所以我们使用 legacy 0.5.15.

I'm replacing $http with Fetch API and got replaced $q with Promise API. Because of that, Angular didn't run digest cycles anymore, thus UI didn't render. To solve this problem I tried Zone.js and that seems to solve our problems partially. Unfortunately its API completely changed in 0.6 so we're using legacy 0.5.15.

现在是实际问题.

刷新页面时,Angular 配置和引导应用程序如预期.在这个阶段,我正在初始化 Zone 并用 Zone 和 $rootScope.$digest() 装饰 $rootScope.apply.现在,当我在状态/路由(使用 ui-router)之间转换时,一切都按预期工作,但是当完全刷新时,会出现竞争条件并且区域/摘要无法正确运行.我不知道如何解决它.

When refreshing the page Angular configs and bootstraps the application like expected. In this phase I'm initializing the Zone and decorating the $rootScope.apply with the Zone and $rootScope.$digest(). Now when I transition between states/routes (with ui-router) everything works as expected, but when full refreshing there's a race condition and the zone/digest doesn't run correctly. I'm not sure how to fix it.

我在 angular.run() 块中有以下代码:

I have the following code in a angular.run() block:

console.log('Zone setup begin');
const scopePrototype = $rootScope.constructor.prototype;
const originalApply = scopePrototype.$apply;
const zoneOptions = {
    afterTask: function afterTask() {
        try {
            $rootScope.$digest();
        } catch (e) {
            $exceptionHandler(e);
            throw e;
        }
    }
};

scopePrototype.$apply = function $applyFn() : void {
    const scope = this;
    const applyArgs = arguments;

    window.zone.fork(zoneOptions).run(() => {
        originalApply.apply(scope, applyArgs);
        console.log('Zone + $digest run!');
    });
};
console.log('Zone setup end');

在上面你可以看到我在 Zone 初始化开始、结束和运行时登录到控制台(+ Angular 摘要循环).在我通过 Fetch API 获取数据的控制器中,我添加了一个 console.log('Data fetched!'); 以便我知道何时获取了数据.

Above you can see that I log to the console when the Zone initialization begins, when it ends and when it's run (+ Angular digest cycle). In my controller where I fetch the data via Fetch API I've added a console.log('Data fetched!'); so I know when the data has been fetched.

现在控制台输出:

使用 ui-router 进行状态转换 (完美运行)

请注意,摘要在最后运行.

Notice that the digest is run in the end.

Zone setup begin
Zone setup end
Zone + $digest run!
Zone + $digest run!
Zone + $digest run!
Zone + $digest run!
Data fetched!
Zone + $digest run!

完全刷新状态/路由 (最后不运行)

Zone setup begin
Zone setup end
Zone + $digest run!
Zone + $digest run!
Zone + $digest run!
Zone + $digest run!
Data fetched!

如您所见,在获取数据后区域/摘要不会运行,这就是数据和 UI 未在页面上呈现的原因.

As you can see the Zone/digest doesn't run after the data is fetched, which is why the data and UI isn't rendered on the page.

推荐答案

转换由 获取 API 到 AngularJS $q 承诺 $q.when.

Convert the ES6 promises created by the fetch API to AngularJS $q promises with $q.when.

AngularJS 通过提供自己的事件处理循环来修改正常的 JavaScript 流程.这将 JavaScript 分为经典和 AngularJS 执行上下文.只有在 AngularJS 执行上下文中应用的操作才能受益于 AngularJS 数据绑定、异常处理、属性监视等...2 由于 promise 来自 AngularJS 框架之外,因此该框架不知道模型的更改并且不会更新 DOM.

AngularJS modifies the normal JavaScript flow by providing its own event processing loop. This splits the JavaScript into classical and AngularJS execution context. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc...2 Since the promise comes from outside the AngularJS framework, the framework is unaware of changes to the model and does not update the DOM.

使用 $q.when 将外部承诺转换为 Angular 框架承诺:

Use $q.when to convert the external promise to an Angular framework promise:

var myRequest = new Request('flowers.jpg');

$q.when(fetch(myRequest)).then(function(response) {
    //code here
})

使用与 AngularJS 框架及其摘要循环正确集成的 $q 服务承诺.

Use $q Service promises that are properly integrated with the AngularJS framework and its digest cycle.

将可能是值或(第 3 方)然后可承诺的对象包装到 $q 承诺中.当您处理可能是也可能不是承诺的对象,或者承诺来自不可信的来源时,这很有用.

$q.when

Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted.

--AngularJS $q 服务 API 参考 - $q.when

这篇关于用 Fetch API 替换 $http的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆