Javascript 角度从外部选择所有复选框ng repeat 描述
我有一个小型产品订单系统,用户可以在其中添加订单行,并在每个订单行上添加一个或多个产品。(我意识到多个产品在同一订单线上是很不寻常的,但这是另一个问题) 每行可选择的产品基于产品的层次结构。例如: 产品展示示例 JSON数据 ]) T恤衫不可选,但3款儿童产品可选 我想要达到的目标 我希望能够做到的是,有一个“全选”按钮,可以自动将这三种产品添加到订单行 第二个要求是,当按下“全选”按钮时,它会根据产品ID排除某些产品。我已经为此创建了一个“排除”数组 我已经设置了一个示例来说明购物车,以及我正在尝试做的事情 到目前为止,它可以:Javascript 角度从外部选择所有复选框ng repeat 描述,javascript,angularjs,angularjs-ng-repeat,Javascript,Angularjs,Angularjs Ng Repeat,我有一个小型产品订单系统,用户可以在其中添加订单行,并在每个订单行上添加一个或多个产品。(我意识到多个产品在同一订单线上是很不寻常的,但这是另一个问题) 每行可选择的产品基于产品的层次结构。例如: 产品展示示例 JSON数据 ]) T恤衫不可选,但3款儿童产品可选 我想要达到的目标 我希望能够做到的是,有一个“全选”按钮,可以自动将这三种产品添加到订单行 第二个要求是,当按下“全选”按钮时,它会根据产品ID排除某些产品。我已经为此创建了一个“排除”数组 我已经设置了一个示例来说明购物车,以及我正
- 添加/删除订单行
- 添加/删除产品
- 为节中的所有产品添加“检查”,不包括“排除”数组中的任何产品
<table class="striped table">
<thead>
<tr>
<td class="col-md-3"></td>
<td class="col-md-6"></td>
<td class="col-md-3"><a ng-click="addLine()" class="btn btn-success">+ Add order line</a></td>
</tr>
</thead>
<tbody>
<tr ng-repeat="line in orderHeader.lines">
<td class="col-md-3">
<ul>
<li ng-repeat="product in products" id="line_{{ line.no }}_product_{{ product.id }}">
{{ product.name }} <a ng-click="selectAll(product.id, line.no)" class="btn btn-primary">Select all</a>
<ul>
<li ng-repeat="child in product.children">
<input type="checkbox"
ng-change="sync(bool, child, line)"
ng-model="bool"
data-category="{{child.id}}"
id="check_{{ line.no }}_product_{{ child.id }}"
ng-checked="isChecked(child.id, line)">
{{ child.name }}
</li>
</ul>
</li>
</ul>
</td>
<td class="col-md-6">
<pre style="max-width: 400px">{{ line }}</pre>
</td>
<td class="col-md-3">
<a ng-click="removeLine(line)" class="btn btn-warning">Remove line</a>
</td>
</tr>
</tbody>
</table>
首先,您没有利用将对象和数组传递到控制器函数中的优势,也没有利用DOM而不是数据模型来尝试更新状态,这确实使事情变得过于复杂 考虑这种简化,即通过
ng模型向每个产品添加checked
属性
<!-- checkboxes -->
<li ng-repeat="child in product.children">
<input ng-model="child.checked" >
</li>
允许控制器中执行以下操作:
$scope.selectAll = function(product, line){
angular.forEach(product.children, function(item){
item.checked=true;
});
line.products=product.children;
}
使用angular,您需要始终首先考虑操作数据模型,并让angular管理DOM
强烈建议阅读:
为什么通过编程选中复选框时不触发ng更改?
因为
if($scope.excluded.indexOf(parseInt(category)) == -1)
{
checkboxes[i].checked = true;
// TODO: Check the checkbox, and set its bool parameter to TRUE
}
仅影响视图(DOM)ng change
与ngModel
一起工作,后者无法意识到复选框在视觉上确实发生了更改
我建议您参考我在中提供的解决方案,它适用于您拥有的任何模型结构(有些人可能称之为角度方式) 您是否可以使用Angular来选中或取消选中,而不是更改DOM?如果您在任何按钮上单击“全选”,然后取消选中任何项目,则该项目将从屏幕上删除。@Werlang我不会试图重写整个应用程序。我只修改了答案中提到的功能,可能在其余部分引入了bug。可以随意修改其余部分,但这意味着基本上要开始over@Werlang我也试着教一些关于改变思维方式的知识,这是非常重要的,而不仅仅是提供代码来完成我几乎要做的一切。我可以让select all/none工作,但是当有多个订单行时,它不工作。在第一行中选择将在所有其他行中添加产品。我在这里更新了Plunker:UI似乎可以工作。如果答案对你有帮助,请随意接受。如果有更多的问题,我看不出它们是什么
var myApp = angular.module('myApp', []);
myApp.controller('CartForm', ['$scope', function($scope) {
var inventory = [
{
id: 1,
name: 'T Shirts',
checked: false,
children: [
{ id: 4, name: 'Round-neck', checked: false, children: [] },
{ id: 5, name: 'V-neck', checked: false, children: [] },
{ id: 6, name: 'String vest (exclude)', checked: false, children: [] }
]
},
{
id: 2,
name: 'Jackets',
checked: false,
children: [
{ id: 7, name: 'Denim jacket', checked: false, children: [] },
{ id: 8, name: 'Glitter jacket', checked: false, children: [] }
]
},
{
id: 3,
name: 'Shoes',
checked: false,
children: [
{ id: 9, name: 'Oxfords', checked: false, children: [] },
{ id: 10, name: 'Brogues', checked: false, children: [] },
{ id: 11, name: 'Trainers (exclude)', checked: false, children: []}
]
}
];
$scope.debug_mode = false;
var products = angular.copy(inventory);
$scope.orderHeader = {
order_no: 1,
total: 0,
lines: [
{
no: 1,
products: products,
total: 0,
quantity: 0
}
]
};
$scope.excluded = [6, 11];
$scope.addLine = function() {
var products = angular.copy(inventory);
$scope.orderHeader.lines.push({
no: $scope.orderHeader.lines.length + 1,
products: products,
quantity: 1,
total: 0
});
$scope.loading = false;
}
$scope.removeLine = function(index) {
$scope.orderHeader.lines.splice(index, 1);
}
$scope.selectAll = function(product){
angular.forEach(product.children, function(item){
if($scope.excluded.indexOf(parseInt(item.id)) == -1) {
item.checked=true;
}
});
}
$scope.removeAll = function(product){
angular.forEach(product.children, function(item){
item.checked=false;
});
}
$scope.toggleDebugMode = function(){
$scope.debug_mode = ($scope.debug_mode ? false : true);
}
}]);
<!-- checkboxes -->
<li ng-repeat="child in product.children">
<input ng-model="child.checked" >
</li>
<a ng-click="selectAll(product,line)">
$scope.selectAll = function(product, line){
angular.forEach(product.children, function(item){
item.checked=true;
});
line.products=product.children;
}
if($scope.excluded.indexOf(parseInt(category)) == -1)
{
checkboxes[i].checked = true;
// TODO: Check the checkbox, and set its bool parameter to TRUE
}