我正在AngularJs制作一个简单的体育用品购物应用程序。
我的情况是我有三个嵌套的ng-repeats。
第一次循环:获取品牌名称。我写了angularjs服务,调用其余端点来获取品牌列表(Adidas,Yonex,Stiga等)。我在页面(控制器)加载后立即调用此服务。
第二次循环:对于每个品牌,我想显示他们提供的产品类别。在这个循环中,我想要执行一个功能/服务,它将品牌名称作为输入,并获得该品牌的所有类别。为此,我还有一个angularjs服务,它调用其余端点来获取给定品牌名称的类别列表。
第三次循环:对于每个品牌和类别,我想显示该类别中的产品。在这个循环中,我想执行一个函数,它将品牌名称和类别作为输入,并获得该类别中的所有产品。我是一个angularjs服务调用,它将调用其余端点来获取给定品牌名称和类别的产品。
示例数据集
Adidas
-----T-Shirts
----------V-Neck
----------RoundNeck
-----Shoes
----------Sports Shoes
----------LifeStyle Shoes
Yonex
-----Badminton Racquet
----------Cabonex
----------Nanospeed
-----Shuttlecocks
----------Plastic
----------Feather
Stiga
-----Paddle
----------Procarbon
----------Semi-carbon
-----Ping Pong Balls
----------Light Weight
----------Heavy Weight
请注意,由于某些限制,我不能在REST端拥有域对象来模仿上面显示的数据结构。
我希望以类似树的方式显示上述数据(可能与展开/折叠选项相同,如上所示)。 以下是代码段。
控制器:
(function () {
'use strict';
angular.module('SportsShoppingApp.controllers').controller('sportsController', ['sportsService', '$scope', function (sportsService, $scope) {
$scope.brands = [];
$scope.categories = [];
$scope.products = {};
$scope.getBrands = function () {
sportsService.getBrands()
.then(loadBrands, serviceError);
};
var loadBrands = function(response) {
$scope.brands= response.data;
};
$scope.getCategories = function(brand) {
sportsService.getCategories(brand)
.then(loadCategories, serviceError);
};
var loadCategories = function (response) {
$scope.categories = response.data;
};
$scope.getProducts = function(brand, category) {
sportsService.getProducts(brand, category)
.then(loadProducts, serviceError);
};
var loadProducts = function (response) {
$scope.products = response.data;
};
var serviceError = function (errorMsg) {
console.log(errorMsg);
};
$scope.getBrands();
}]);
}());
HTML:
<div class="well">
<div class="row">
<div id="sportsHeader" class="col-md-3">
<div ng-repeat="brand in brands.data">
<div class="row">
<div class="col-md-9">{{brand}}</div>
</div>
<div ng-repeat="category in categories.data" ng-init="getCategories(brand)">
<div class="row">
<div class="col-md-9">{{category}}</div>
</div>
<div ng-repeat="product in products.data" ng-init="getProducts(brand, category)">
<div class="row">
<div class="col-md-9">{{product}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
当我使用上述HTML时,UI上只显示品牌名称。不显示类别及其相应的产品。我知道正在发生一些重叠。我不确定我是否正确地做到了这一点。我的方法可能完全错了。我是AngularJS的新手。我想知道如何在嵌套的ng-repeat中循环,以便每个ng-repeat可以调用angularjs服务,并且我还想以树形方式显示数据,如上所示。有人可以帮助我吗?
答案 0 :(得分:0)
我认为ng-init
必须放在ng-repeat
s的单独标签上:
<div class="well">
<div class="row">
<div id="sportsHeader" class="col-md-3">
<div ng-repeat="brand in brands.data">
<div class="row">
<div class="col-md-9">{{brand}}</div>
</div>
<div ng-init="getCategories(brand)">
<div ng-repeat="category in categories.data">
<div class="row">
<div class="col-md-9">{{category}}</div>
</div>
<div ng-init="getProducts(brand, category)">
<div ng-repeat="product in products.data">
<div class="row">
<div class="col-md-9">{{product}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
你可能也需要同时处理你的引导类,移动ng-init
只是为了修复角部分。
答案 1 :(得分:0)
将ng-init
指令移到他们提供数据的ng-repeat
之外。
<div class="well">
<div class="row">
<div id="sportsHeader" class="col-md-3">
<!-- MOVE init of categories here -->
<div ng-repeat="brand in brands.data" ng-init="getCategories(brand)">
<div class="row">
<div class="col-md-9">{{brand}}</div>
</div>
<!-- MOVE init of products here -->
<div ng-repeat="category in categories.data" ng-init="getProducts(brand, category)">
<div class="row">
<div class="col-md-9">{{category}}</div>
</div>
<div ng-repeat="product in products.data">
<div class="row">
<div class="col-md-9">{{product}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
ng-init
指令的优先级为450; ng-repeat
,优先级为1000.这意味着当它们位于同一元素上时ng-init
执行 ng-repeat
指令后的。 ng-repeat
的{{1}}不会执行其categories.data
,直到它有一个类别。因此,ng-init
不能用于填充ng-init
数组。
快速提问。我的方法是否正确?
该方法有效,但它违反了Zen of Angular和MV* Model View Whatever框架的原则。
模型是Single Source of Truth
因为视图只是模型的投影,所以控制器与视图完全分离并且不知道它。这使得测试变得简单,因为在没有视图和相关的DOM /浏览器依赖性的情况下,可以轻松地单独测试控制器。
使用categories
和ng-repeat
指令构建模型会创建一个依赖项,使测试和调试变得困难。 (正如这个问题所证明的那样。)
我的建议是学习如何chaining promises并使用$q.all来构建模型。