2016-02-17 54 views
1

我已經在網上查了幾個解決方案,但我不太明白如何停止加載控制器。所以,我創建了一個強調突出我想要做的事情。Angularjs:在服務中加載數據然後將其加載到控制器

基本上:我想加載服務中的所有數據,然後將該服務中的數據傳遞給每個控制器。當應用程序第一次加載時,因爲它是異步的,控制器首先被加載。

我可以只使用工廠的每個控制器,但我想保持在該服務的「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

+0

選中此項:http://plnkr.co/edit/x90U7d0wzkSeCVNu3Vdl?p=preview –

+0

謝謝,鮑勃。是的,我知道這個實現,儘管只需要在控制器中調用'productsFactory.getProds(function(data){$ scope.myProducts = data})'而不用通過服務 - 我的興趣是如果有一種解決方案只需調用一次http請求,並將數據保存在變量中,然後將其傳遞給控制器​​。謝謝 –

回答

0

最後!!!我管理着做我正在尋找的東西。

注意,這並不一定是最好的做法,但它是被竊聽我一個問題,想知道它是如何做。

我做的是創建一個全局變量,在這裏我用一個主要的決心功能等待工廠做HTTP GET,然後將它傳遞給服務的方式。然後,我使用每個需要該數據和引用該功能的狀態的解決方案。

UPDATE:意識到每當狀態爲changins時我都調用了相同的工廠函數,因此我決定使用一個變量 - appService中的一個屬性,當http get被調用一次時變爲true:appService。檢索並改變了主要的解析功能。

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

再次,工廠可以多一些重構和消除類似的一些代碼緩存數據。這樣,我們只會去一次工廠功能。

2

我沒有實際測試,但看起來你需要創建和以有數據返回一個承諾返回。

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; 
    } 
]); 
1

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

的變化:
- 一個主要的應用程序控制器,封裝所有的應用程序。
在此控制器中,如果引導尚未完成所有作業,我們將阻止路線更改。啓動完成後,我們將位置更改爲主/默認路徑。
- 在我們run塊,我們設定的bootStatus VAR來false,等到產品被取出。

另外,我存儲結果,從服務到$rootScope所以你可以用在所有的控制器的數據沒有一遍又一遍注射服務。

相關問題