簡體   English   中英

Angularjs:在服務中加載數據然后將其加載到控制器

[英]Angularjs: load data in service then load it to controllers

我在網上查了幾個解決方案,但我不太明白如何阻止控制器加載。 所以,我已經創建了一個plunkr來突出我想要做的事情。

基本上:我想加載服務中的所有數據,然后將該數據從該服務傳遞到每個控制器。 當應用程序首次加載時,因為它是Async,所以首先加載控制器。

我本可以在每個控制器中使用工廠,但我希望將該數據保存在服務的“allProducts”屬性中。 我沒有看到每次加載視圖時都需要調用工廠函數。

在這個例子中,我也嘗試過使用$ q服務,但在我看來,它具有與工廠中的http相同的行為,並且仍然需要在每個視圖加載時調用http請求...

那么,有人可以幫我解決這個例子並實現一個優雅的解決方案嗎?

app.factory('productsFactory', ['$http', '$q',
    function($http, $q) {
        var cachedData; //here we hold the data after the first api call  
        function getData(callback) {
            if (cachedData) {
                callback(cachedData);
            } else {
                $http.get('http://api.bestbuy.com/v1/products(longDescription=iPhone*|sku=7619002)?show=sku,name&pageSize=15&page=5&apiKey=bqs7a4gwmnuj9tq6bmyysndv&format=json')
                    .success(function(data) {
                        cachedData = data; //caching the data in a local variable
                        callback(data);
                    });
            }
        }

        return {
            getProds: getData
        }
    }
])

app.service('appService', ['productsFactory', '$q',
    function(productsFactory, $q) {
        var _this = this;
        productsFactory.getProds(function(data) {
            _this.allProducts = data; //wait for data to load before loading the controllers
        })

    }
])

app.controller('productsCtrl', ['$scope', 'appService',
    function($scope, appService) {
        $scope.myProducts = appService.allProducts;
    }
]);

plunkr: http ://plnkr.co/edit/ZvtYwXHSasC3fCAZKkDF?p = preview

我實際上沒有測試它,但看起來你需要創建並返回一個promise,以便在可用時返回數據。

    app.factory('productsFactory', ['$http', '$q',
    function($http, $q) {

        var cachedData; //here we hold the data after the first api call  
        function getData(callback) {
var d = $q.defer();
            if (cachedData) {
d.resolve(callback(cachedData));

            } else {
                $http.get('http://api.bestbuy.com/v1/products(longDescription=iPhone*|sku=7619002)?show=sku,name&pageSize=15&page=5&apiKey=bqs7a4gwmnuj9tq6bmyysndv&format=json')
                    .success(function(data) {
                        cachedData = data; //caching the data in a local variable
                        d.resolve(callback(cachedData));
                    });
            }
return d.promise;
        }

        return {
            getProds: getData
        }
    }
])

app.service('appService', ['productsFactory', '$q',
    function(productsFactory, $q) {
        var _this = this;
        productsFactory.getProds(function(data) {
            _this.allProducts = data; //wait for data to load before loading the controllers
        })

    }
])

app.controller('productsCtrl', ['$scope', 'appService',
    function($scope, appService) {
        $scope.myProducts = appService.allProducts;
    }
]);

檢查一下: http//plnkr.co/edit/ey0na3l2lyT0tUdbDyrf?p = preview

變化:
- 包裝所有應用程序的主應用程序控制器。
在此控制器中,如果引導尚未完成所有作業,我們會阻止路由更改。 啟動完成后,我們將位置更改為主/默認路由。
- 在我們的run塊中,我們將bootStatus var設置為false並等待產品被提取。

此外,我已將服務的結果存儲到$rootScope因此您可以在所有控制器中使用該數據,而無需反復注入服務。

最后!!! 我管理做我想要的。

請注意,這不一定是最佳做法,但這是一個困擾我的問題,並想知道它是如何完成的。

我這樣做的方法是創建一個全局變量,我使用main resolve函數等待工廠執行http get,然后將其傳遞給服務。 然后,我在需要該數據的每個狀態上使用resolve並引用該函數。

更新:實現每次狀態變化時我都調用相同的工廠函數,所以我決定使用變量 - appService中的一個屬性,當http get被調用一次時變為true:appService.retrieved並更改了主要解決功能一點。

var mainResolve = ['$q', 'appService', 'productsFactory', function($q, appService, productsFactory) {
var defer = $q.defer();
if(appService.retrieved) {
    defer.resolve();
} else {
  productsFactory.getProds(function(data) {
      appService.allProducts = data;
      defer.resolve();
  })
  appService.retrieved = true;
}

return defer.promise;
}]

而在州

.state('home', {
  url: "/home",
  templateUrl: "home.html",
  controller: 'homeCtrl',
  resolve: {
    waitingFor: mainResolve
  }
})

您可以在這里找到帶有工作解決方案的plnkr: http ://plnkr.co/edit/ZvtYwXHSasC3fCAZKkDF?p = preview

同樣,工廠可以進行更多重構,並消除一些代碼,如緩存數據。 這樣,我們只去了一次工廠功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM