用Fetch API替换$ http

Gau*_*aui 5 javascript angularjs angularjs-http angular-promise fetch-api

我将替换$http为Fetch API,然后将其替换$q为Promise API。因此,Angular不再运行摘要循环,因此UI无法呈现。为了解决这个问题,我尝试了Zone.js,这似乎可以部分解决我们的问题。不幸的是,其API在0.6中已完全更改,因此我们使用的是旧版0.5.15

现在到实际问题了。

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

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

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');
Run Code Online (Sandbox Code Playgroud)

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

现在在控制台中输出:

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

请注意,摘要最后运行。

Zone setup begin
Zone setup end
Zone + $digest run!
Zone + $digest run!
Zone + $digest run!
Zone + $digest run!
Data fetched!
Zone + $digest run!
Run Code Online (Sandbox Code Playgroud)

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

Zone setup begin
Zone setup end
Zone + $digest run!
Zone + $digest run!
Zone + $digest run!
Zone + $digest run!
Data fetched!
Run Code Online (Sandbox Code Playgroud)

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

geo*_*awg 2

使用$q.when将fetch API创建的 ES6 Promise 转换为 AngularJS $q Promise 。

用于$q.when将 ES6 Promise 转换为 AngularJS Promise 1

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

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

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

$q.when(fetch(myRequest)).then(function(response) {
    //code here
})
Run Code Online (Sandbox Code Playgroud)

使用与 AngularJS 框架及其摘要周期正确集成的 $q 服务承诺。

$q.when

将可能是值或(第 3 方)then-able Promise 的对象包装到 Promise 中$q。当您处理的对象可能是也可能不是承诺,或者承诺来自不可信的来源时,这非常有用。

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