我想從服務器中使用Angular應用程序的主控制器中的$資源加載JSON對象。有一些路徑加載部分到ng-view中顯示數據,分頁等。瞭解使用AngularJS承諾,他們將如何幫助解決此問題
這一切工作正常,但我的下一個目標是過濾基於單擊鏈接的數據,並更新URL,以便用戶可以鏈接到過濾的數據(domain.dev/products/brandname)。
只要站點從根URL或其他任何不會將路由調用到產品的URL加載,一切都很好,但只要我試圖從/ products中加載站點,它就會中斷,因爲在路由將部分加載到視圖之前,數據不可用。
我想了解一個承諾是否有助於解決這個問題,如果有的話,從哪裏開始。我一直在做一些關於承諾的閱讀,我相當肯定這是答案,但我無法使它與現有代碼一起工作。
我使用$資源,因爲它看起來很乾淨,但也許$ http會在這裏做得更好,因爲它有更多選項。
簡單地說,當網站從/加載時,一切都很好,因爲使用JSON的部分還沒有,當它們加載時,數據已準備就緒。但是,當加載部分的控制器在網站加載時被調用時,數據不存在,並且當我嘗試設置一些增值時,ProductController會引發錯誤。由於$ scope.products不存在,它沒有長度的方法。我把整個代碼部分包裝在一個帶有ng-show =「products」的div中,但是由於錯誤似乎是在控制器中拋出,所以在這種情況下我不能正常工作。部分仍會加載,但{{vars}}可見。
任何指導,將不勝感激。
編輯:我不是試圖將URL參數發送到端點,我實際上想要所有的數據,然後篩選與Angular。基本上,我希望主應用程序下載所有的數據(並不多),並準備就緒,無論/ products/string是否爲路徑。我的目標是避免爲每個過濾器進行HTTP調用。我有這樣的工作,但只有幾個項目等待HTTP結果的時間太長。我的主要問題是我可以獲取數據,但是當數據從服務器返回時,ProductController已經運行並引發錯誤。基本上,我希望控制器在嘗試運行之前等待數據。
編輯2:我想出了問題,這更多的是我試圖構建我的應用程序的方式。我認爲分離代碼的最好方法是將產品放在自己的控制器中,但也想通過預先加載數據,我需要在主appController中調用服務。那是我的錯誤。一旦我將所有代碼移入appController
並更改了產品路由
中的控制器,它就會按需要工作。我被提示更多地瞭解承諾,這很好,我能夠使用我學到的東西。仍然存在過濾問題,但是這解決了這個問題。
我得到了這個職位的一些幫助:AngularJS: Waiting for an asynchronous call
這裏是工作代碼:
elite.controller('productController', function($scope, $routeParams, $rootScope, $location, Products){
$scope.brand = $routeParams.brand;
$rootScope.productPagination = function(){
$scope.currentPage = 1;
$scope.numPerPage = 10;
$scope.maxSize = 6;
$scope.totalItems = $rootScope.products.length;
$scope.numPages = Math.ceil($scope.totalItems/$scope.numPerPage);
$scope.$watch('currentPage + numPerPage', function() {
var begin = (($scope.currentPage - 1) * $scope.numPerPage)
, end = begin + $scope.numPerPage;
$scope.filteredProducts = $rootScope.products.slice(begin, end);
});
}
if (!$rootScope.products){
Products.getProducts().then(function(data){
$rootScope.products = data.products;
$rootScope.productPagination();
});
}else{
$rootScope.productPagination();
}
});
這裏是應用程序(冷凝)迄今:
var elite = angular.module("elite", ["ngResource", "ngSanitize", "ui.bootstrap"]);
elite.config(['$routeProvider', function($routeProvider){
$routeProvider.when('/', {
templateUrl: 'partials/home.html',
controller: 'homeController'
})
$routeProvider.when('/products', {
templateUrl:'partials/products.html',
controller: 'productController'
})
$routeProvider.when('/products/:brand', {
templateUrl:'partials/products.html',
controller: 'productController'
})
$routeProvider.otherwise({redirectTo :'/'})
}]);
elite.factory('Products', function($resource){
return $resource("/products")
});
elite.controller('appController', function($scope, $location, $routeParams, Products){
Products.get({},function (data){
$scope.products = data.products;
});
});
elite.controller('productController', function($scope, $location, $routeParams, $resource){
$scope.brand = $routeParams.brand;
$scope.currentPage = 1;
$scope.numPerPage = 10;
$scope.maxSize = 6;
$scope.$watch($scope.products, function(){
$scope.numPages = Math.ceil($scope.products.length/$scope.numPerPage);
$scope.$watch('currentPage + numPerPage', function() {
var begin = (($scope.currentPage - 1) * $scope.numPerPage)
, end = begin + $scope.numPerPage;
$scope.totalItems = $scope.products.length;
$scope.filteredProducts = $scope.products.slice(begin, end);
});
});
});
<div ng-show="products">
<h2>{{ brand }} products...</h2>
<h4>{{products.length}} items</h4>
<pagination ng-show="numPages" total-items="totalItems" page="currentPage" max-size="maxSize" class="pagination-small" boundary-links="true" rotate="false" num-pages="numPages"></pagination>
<table class="table table-striped">
<tr ng-repeat="product in filteredProducts">
<td>{{product.brand}}</td>
<td>{{product.title}}</td>
<td ng-bind="product.priceDealer | currency"></td>
<td>{{product.msrp | currency}}<td>
</tr>
</table>
</div>
謝謝您的回答。我試過你的解決方案,但仍然有問題。似乎沒有返回數據。另外,$資源需要注入到服務中。實際上我並不想將參數傳遞給端點,我想先獲得完整的負載(這不是很多項目),然後使用Angular在數據加載後對其進行過濾。也許我並不清楚這一點。我正在閱讀你所建議的PDF,也許我可以在那裏選擇一些能夠幫助我理解它如何工作的東西。 – Jazzy
雖然這不是確切的正確答案,但它爲我提供了去正確的地方的知識。我會考慮這個答案。 – Jazzy