2

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

问题是 API 调用是异步的:

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

我正在尝试创建一个工厂,它将返回 API 返回的 JSON 对象。但是,由于调用是异步的,所以我不知道如何实现工厂方法。

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

这是我目前拥有的:

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调用需要很长时间,当用户去使用它时,会话对象会被未初始化。

4

2 回答 2

0

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

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

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;
    };
}

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

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",控制器最终变得更加直接:

function ($scope, someFactory) {

    $scope.someCondition = true;

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

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

于 2015-03-11T20:11:41.343 回答
0

您始终可以使用 ngIf 并等待满足要求。

<div ng-if="session" session-toolbox></div>

这样,一旦设置了会话,您就可以在 DOM 中使用指令会话工具箱。

但是,如果您在当前范围之外收集这些数据,那么您应该 $broadcast 自定义事件并在所需控制器内监听该事件。

于 2014-03-19T15:24:03.750 回答