2

我想使當前登錄的用戶ID和用戶名可用於我的Angular指令。我創建了一個API端點來檢索這些信息(以及其他一些信息)。AngularJS - 涉及異步數據的依賴注入

的問題是,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調用需要很長時間,會話對象將在用戶使用它時被初始化。

+0

退房$廣播。當出廠值發生變化並且需要通知您的控制器/指令時,這非常棒。 –

回答

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中傾銷太多。

0

您可以隨時使用ngIf並等待要求完成。

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

這樣,一旦設置了會話,您就可以在DOM中使用指令會話工具箱。

但是,如果您在當前範圍之外收集此數據,則應該廣播自定義事件並在所需控制器內偵聽該事件。