AngularJS - 涉及异步数据的依赖注入 [英] AngularJS - Dependency injection involving asynchronous data

查看:25
本文介绍了AngularJS - 涉及异步数据的依赖注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想让当前登录的用户 ID 和用户名可用于我的 Angular 指令.我创建了一个 API 端点来检索此信息(以及一些其他信息).

I want to make the currently logged in user's ID and user name available to my Angular directives. I have created an API end-point to retrieve this information (along with some other information).

问题在于API调用是异步的:

The problem is that the API call is asynchronous:

var url = baseUrl + 'api/sessions';
$http.get(url)

我正在尝试创建一个工厂,该工厂将返回 API 返回的 JSON 对象.不过由于调用是异步的,不知道工厂方法怎么实现.

I am trying to create a factory that will return the JSON object returned by the API. However, since the call is asynchronous, I don't know how to implement the factory method.

此外,我不想在值从 API 返回之前实例化指令.AngularJS 中是否有一种机制可以确保异步调用首先返回,还是应该创建一个全局对象并在调用返回时更新其值(使用 JSON 对象)?

Additionally, I don't want to instantiate the directives until after the value comes back from the API. Is there a mechanism built in to AngularJS that will make sure the asynchronous call has returned first, or should I just create a global object and update its values when the call returns (using the JSON object)?

这是我目前拥有的:

application.factory('session', ['$http', 'baseUrl', function ($http, baseUrl) {
    var session = {};
    var url = baseUrl + 'api/sessions';
    var promise = $http.get(url)
        .success(function (data) {
            for (var key in data) {
                session[key] = data[key];
            }
        });
    return session;
}]);

问题是任何依赖指令都在填充会话对象之前检索它.我担心如果 API 调用需要很长时间,会话对象会在用户使用时未初始化.

The problem is that any dependent directives are retrieving the session object before it is populated. I am concerned that if the API call takes a long time, the session object will be uninitialized when the user goes to use it.

推荐答案

事实证明,当谈到 AngularJS 时,我遵循了一种非常讨厌的反模式.我正在将属性绑定到我的 HTML 中的函数.大多数情况下,这是采用 ng-disabled="isThisFieldDisabled()" 的形式.

It turns out I was following a pretty nasty anti-pattern when it comes to AngularJS. I was binding attributes to functions in my HTML. Most often, this was in the form of ng-disabled="isThisFieldDisabled()".

问题是我在计算每次调用函数时是否应该禁用该字段.在异步加载数据的情况下,这些函数首先需要检查数据是否已经加载.

The problem was I was calculating whether the field should be disabled every time the function was called. In cases where the data was loaded asynchronously, these functions would first need to check if the data had been loaded yet.

function ($scope, someFactory) {

    someFactory.then(function (data) {
        $scope.data = data;
    });

    $scope.isThisFieldDisable = function () {
        if (!angular.isDefined($scope.data)|| $scope.data === null) {
            return true;
        }
        return $scope.data.someCondition;
    };
}

更简单的方法是在调用返回数据时简单地更新条件:

A much easier approach is to simply update the condition when the data is returned from the call:

function ($scope, someFactory) {

    $scope.someCondition = true;

    someFactory.then(function (data) {
        $scope.someCondition = data.someCondition;
    });

    $scope.isThisFieldDisable = function () {
        return $scope.someCondition;
    };
}

当然,一旦您只是返回 $scope 值,该函数就变得不必要了.您可以像这样更新 HTML ng-disabled="someCondition" 并且控制器最终会更直接:

Of course, once you are just returning the $scope value, the function becomes unnecessary. You can update the HTML like so ng-disabled="someCondition" and the controller ends up much more straight-forward:

function ($scope, someFactory) {

    $scope.someCondition = true;

    someFactory.then(function (data) {
        $scope.someCondition = data.someCondition;
    });
}

在大多数情况下,我实际上将我的 $scope 函数转换为本地函数.它们包含计算"支持字段值的逻辑,因此从 $http 回调中调用它们是有意义的.我通常不得不添加参数,因为我不再在 $scope 中倾倒那么多.

In most cases, I actually converted my $scope functions into local functions. They contained the logic for "calculating" the value of the backing field, so it made sense to call them from the $http callbacks. I usually had to add parameters since I wasn't dumping as much in the $scope anymore.

这篇关于AngularJS - 涉及异步数据的依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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