Javascript 角度从外部选择所有复选框ng repeat 描述

Javascript 角度从外部选择所有复选框ng repeat 描述,javascript,angularjs,angularjs-ng-repeat,Javascript,Angularjs,Angularjs Ng Repeat,我有一个小型产品订单系统,用户可以在其中添加订单行,并在每个订单行上添加一个或多个产品。(我意识到多个产品在同一订单线上是很不寻常的,但这是另一个问题) 每行可选择的产品基于产品的层次结构。例如: 产品展示示例 JSON数据 ]) T恤衫不可选,但3款儿童产品可选 我想要达到的目标 我希望能够做到的是,有一个“全选”按钮,可以自动将这三种产品添加到订单行 第二个要求是,当按下“全选”按钮时,它会根据产品ID排除某些产品。我已经为此创建了一个“排除”数组 我已经设置了一个示例来说明购物车,以及我正

我有一个小型产品订单系统,用户可以在其中添加订单行,并在每个订单行上添加一个或多个产品。(我意识到多个产品在同一订单线上是很不寻常的,但这是另一个问题)

每行可选择的产品基于产品的层次结构。例如:

产品展示示例 JSON数据 ])

T恤衫不可选,但3款儿童产品可选

我想要达到的目标 我希望能够做到的是,有一个“全选”按钮,可以自动将这三种产品添加到订单行

第二个要求是,当按下“全选”按钮时,它会根据产品ID排除某些产品。我已经为此创建了一个“排除”数组

我已经设置了一个示例来说明购物车,以及我正在尝试做的事情

到目前为止,它可以:

  • 添加/删除订单行
  • 添加/删除产品
  • 为节中的所有产品添加“检查”,不包括“排除”数组中的任何产品
问题 但是,尽管它在输入中添加了检查,但不会触发输入上的ng更改:

<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     
  }