【问题标题】:Angular 2: Get Values of Multiple Checked CheckboxesAngular 2:获取多个选中复选框的值
【发布时间】:2016-05-02 00:42:41
【问题描述】:

我的问题很简单:我有一个这样的复选框列表:

<div class="form-group">
    <label for="options">Options :</label>
    <label *ngFor="#option of options" class="form-control">
        <input type="checkbox" name="options" value="option" /> {{option}}
    </label>
</div>

我想发送一组选定选项,例如: [option1, option5, option8] 如果选择了选项 1、5 和 8。这个数组是我想通过 HTTP PUT 请求发送的 JSON 的一部分。

感谢您的帮助!

【问题讨论】:

    标签: json forms checkbox angular angular2-forms


    【解决方案1】:
    <input type="checkbox" name="options" value="option" (change)="updateChecked(option, $event)" /> 
    
    export class MyComponent {
      checked: boolean[] = [];
      updateChecked(option, event) {
        this.checked[option]=event; // or `event.target.value` not sure what this event looks like
      }
    }
    

    【讨论】:

    • this.checked 勾选或取消勾选后返回[undefined: Event] 为什么?
    • 我不知道this.checked 应该在什么时候引用。你能创建一个 Plunker 吗?
    • 对不起,我只看问题的来源,而不是我的答案;-p。 option 未定义。如果您添加具有此名称的字段,则它不再是未定义的(请参阅plnkr.co/edit/MsJDlEimeeeV4Wk3NNk5?p=preview)。在问题中option*ngFor="#option of xxx" 的值变量。它只需要存在于范围内。
    • 很抱歉,但您的 plnkr 仍然很困惑如何获取已检查的 checkbxoes 列表?
    • 一个例子plnkr.co/edit/N9NXBYcwhon6ITr8RP5y?p=preview 有不同的方法来存储选中状态(使用选项,或者存储索引而不是值,...)
    【解决方案2】:

    感谢 Gunter,我找到了解决方案!如果它可以帮助任何人,这是我的整个代码:

    <div class="form-group">
                <label for="options">Options :</label>
                <div *ngFor="#option of options; #i = index">
                    <label>
                        <input type="checkbox"
                               name="options"
                               value="{{option}}"
                               [checked]="options.indexOf(option) >= 0"
                               (change)="updateCheckedOptions(option, $event)"/>
                        {{option}}
                    </label>
                </div>
            </div>
    

    这是我正在使用的 3 个对象:

    options = ['OptionA', 'OptionB', 'OptionC'];
    optionsMap = {
            OptionA: false,
            OptionB: false,
            OptionC: false,
    };
    optionsChecked = [];
    

    还有3个有用的方法:

    1。发起optionsMap

    initOptionsMap() {
        for (var x = 0; x<this.order.options.length; x++) {
            this.optionsMap[this.options[x]] = true;
        }
    }
    

    2.更新optionsMap

    updateCheckedOptions(option, event) {
       this.optionsMap[option] = event.target.checked;
    }
    

    3.在发送POST请求之前将optionsMap转换成optionsChecked并存储在options中:

    updateOptions() {
        for(var x in this.optionsMap) {
            if(this.optionsMap[x]) {
                this.optionsChecked.push(x);
            }
        }
        this.options = this.optionsChecked;
        this.optionsChecked = [];
    }
    

    【讨论】:

    • 我认为根据您的解决方案,它必须知道复选框数组的所有值不是吗?
    • 看我的回答。希望它可以帮助你。如果您不知道数组的长度,甚至不知道所有条目,代码运行不会出错。尝试给定的 Plnkr
    • 这应该没那么难,为什么 ngModel 不处理它:(
    • 我相信我在这里的回答:stackoverflow.com/a/41027266/4496240,会更适合这个,因为它需要的工作要少得多,并且以更加“有角度”的方式完成。它还针对新的表单库进行了更新。
    • @YannickMorel 你是怎么写这个帖子请求的?因为我有同样的问题,我和你写的一样,但我不知道如何处理发布请求以将其作为数组发送
    【解决方案3】:

    这是使用ngModel(最终Angular 2)的简单方法

    <!-- my.component.html -->
    
    <div class="form-group">
        <label for="options">Options:</label>
        <div *ngFor="let option of options">
            <label>
                <input type="checkbox"
                       name="options"
                       value="{{option.value}}"
                       [(ngModel)]="option.checked"/>
                {{option.name}}
            </label>
        </div>
    </div>
    

    // my.component.ts
    
    @Component({ moduleId:module.id, templateUrl:'my.component.html'})
    
    export class MyComponent {
      options = [
        {name:'OptionA', value:'1', checked:true},
        {name:'OptionB', value:'2', checked:false},
        {name:'OptionC', value:'3', checked:true}
      ]
    
      get selectedOptions() { // right now: ['1','3']
        return this.options
                  .filter(opt => opt.checked)
                  .map(opt => opt.value)
      }
    }
    

    【讨论】:

    • 您将如何访问选定的选项?我对get函数声明不熟悉
    • 去掉()(即this.selectedOptions而不是this.selectedOptions()
    • 如何触发 selectedOptions 事件,因为 html 中没有事件
    • 不获取 selectedOptions 在每个用户操作(单击、按键等)上被调用以进行评估。如果选项数组很大,可能会导致性能问题。
    【解决方案4】:
    1. 我只是为那些使用列表的人简化了一点 价值对象。 XYZ.Comonent.html

      <div class="form-group">
              <label for="options">Options :</label>
              <div *ngFor="let option of xyzlist">
                  <label>
                      <input type="checkbox"
                             name="options"
                             value="{{option.Id}}"
      
                             (change)="onClicked(option, $event)"/>
                      {{option.Id}}-- {{option.checked}}
                  </label>
              </div>
              <button type="submit">Submit</button>
          </div> 
      

      ** XYZ.Component.ts**.

    2. 创建一个列表 -- xyzlist。

    3. 赋值,我在这个列表中传递来自 Java 的值。
    4. 值是 Int-Id,经过布尔检查(可以在 Component.ts 中传递)。
    5. 现在在 Componenet.ts 中获取价值。

      xyzlist;//Just created a list
      onClicked(option, event) {
          console.log("event  " + this.xyzlist.length);
          console.log("event  checked" + event.target.checked);
          console.log("event  checked" + event.target.value);
          for (var i = 0; i < this.xyzlist.length; i++) {
              console.log("test --- " + this.xyzlist[i].Id;
              if (this.xyzlist[i].Id == event.target.value) {
                  this.xyzlist[i].checked = event.target.checked;
              }
              console.log("after update of checkbox" + this.xyzlist[i].checked);
      
          }
      

    【讨论】:

      【解决方案5】:

      我遇到了同样的问题,现在我有一个我更喜欢的答案(可能你也是)。我已将每个复选框绑定到一个数组索引。

      首先我定义了一个像这样的对象:

      SelectionStatusOfMutants: any = {};
      

      那么复选框是这样的:

      <input *ngFor="let Mutant of Mutants" type="checkbox"
      [(ngModel)]="SelectionStatusOfMutants[Mutant.Id]" [value]="Mutant.Id" />
      

      如您所知,JS 中的对象是具有任意索引的数组。因此,获取结果非常简单:

      像这样计算选定的:

      let count = 0;
          Object.keys(SelectionStatusOfMutants).forEach((item, index) => {
              if (SelectionStatusOfMutants[item])
                  count++;
          });
      

      类似于这样获取选定的:

      let selecteds = Object.keys(SelectionStatusOfMutants).filter((item, index) => {
              return SelectionStatusOfMutants[item];
          });
      

      你看到了吗?!很简单很漂亮。 TG。

      【讨论】:

      • 非常感谢你,我正在做一些有趣的事情。你在这个深夜救了我:-)
      • @ConductedClever 你能为此创建一个堆栈闪电战吗?
      【解决方案6】:

      我希望这会对遇到同样问题的人有所帮助。

      模板.html

      <form [formGroup] = "myForm" (ngSubmit) = "confirmFlights(myForm.value)">
        <ng-template ngFor [ngForOf]="flightList" let-flight let-i="index" >
           <input type="checkbox" [value]="flight.id" formControlName="flightid"
               (change)="flightids[i]=[$event.target.checked,$event.target.getAttribute('value')]" >
        </ng-template>
      </form>
      

      组件.ts

      flightids 数组将有另一个这样的数组 [[真,'id_1'],[假,'id_2'],[真,'id_3']...] 这里 true 表示用户选中它,false 表示用户选中然后取消选中它。 用户从未检查过的项目不会被插入到数组中。

      flightids = []; 
      confirmFlights(value){  
          //console.log(this.flightids);
      
          let confirmList = [];
          this.flightids.forEach(id => {
            if(id[0]) // here, true means that user checked the item 
              confirmList.push(this.flightList.find(x => x.id === id[1]));
          });
          //console.log(confirmList);
      
      }
      

      【讨论】:

        【解决方案7】:

        我刚刚遇到了这个问题,并决定尽可能减少变量,以保持工作空间干净。这是我的代码示例

        <input type="checkbox" (change)="changeModel($event, modelArr, option.value)" [checked]="modelArr.includes(option.value)" />
        

        调用改变的方法是在模型中推值或删除它。

        public changeModel(ev, list, val) {
          if (ev.target.checked) {
            list.push(val);
          } else {
            let i = list.indexOf(val);
            list.splice(i, 1);
          }
        }
        

        【讨论】:

          【解决方案8】:

          创建一个类似的列表:-

          this.xyzlist = [
            {
              id: 1,
              value: 'option1'
            },
            {
              id: 2,
              value: 'option2'
            }
          ];
          

          HTML :-

          <div class="checkbox" *ngFor="let list of xyzlist">
                      <label>
                        <input formControlName="interestSectors" type="checkbox" value="{{list.id}}" (change)="onCheckboxChange(list,$event)">{{list.value}}</label>
                    </div>
          

          然后在它的组件 ts 中:-

          onCheckboxChange(option, event) {
               if(event.target.checked) {
                 this.checkedList.push(option.id);
               } else {
               for(var i=0 ; i < this.xyzlist.length; i++) {
                 if(this.checkedList[i] == option.id) {
                   this.checkedList.splice(i,1);
                }
              }
            }
            console.log(this.checkedList);
          }
          

          【讨论】:

          • 卡住了好几个小时才弄清楚这个问题。这个解决方案很有魅力!
          【解决方案9】:

          上面的@ccwasden 解决方案对我有用,只需稍作改动,每个复选框必须有一个唯一的名称,否则绑定将不起作用

          <div class="form-group">
              <label for="options">Options:</label>
              <div *ngFor="let option of options; let i = index">
                  <label>
                      <input type="checkbox"
                             name="options_{{i}}"
                             value="{{option.value}}"
                             [(ngModel)]="option.checked"/>
                      {{option.name}}
                  </label>
              </div>
          </div>
          
          // my.component.ts
          
          @Component({ moduleId:module.id, templateUrl:'my.component.html'})
          
          export class MyComponent {
            options = [
              {name:'OptionA', value:'1', checked:true},
              {name:'OptionB', value:'2', checked:false},
              {name:'OptionC', value:'3', checked:true}
            ]
          
            get selectedOptions() { // right now: ['1','3']
              return this.options
                        .filter(opt => opt.checked)
                        .map(opt => opt.value)
            }
          }
          

          并且还让 sur 在你的主模块中导入 FormsModule

          import { FormsModule } from '@angular/forms';
          
          
          imports: [
              FormsModule
            ],
          

          【讨论】:

            【解决方案10】:

            由于我花了很长时间解决类似的问题,所以我正在回答以分享我的经验。 我的问题是一样的,要知道,在触发指定事件后获得许多复选框值。 我尝试了很多解决方案,但对我来说最性感的是使用 ViewChildren

            import { ViewChildren, QueryList } from '@angular/core';
            
            /** Get handle on cmp tags in the template */
            @ViewChildren('cmp') components: QueryList<any>;
            
            ngAfterViewInit(){
                // print array of CustomComponent objects
                console.log(this.components.toArray());
            }
            

            在这里找到:https://stackoverflow.com/a/40165639/4775727

            可能的其他参考解决方案,有很多类似的主题,他们都没有针对这个解决方案......:

            【讨论】:

              【解决方案11】:

              这是一个没有地图、“已检查”属性和 FormControl 的解决方案。

              app.component.html:

              <div *ngFor="let item of options">
                <input type="checkbox" 
                (change)="onChange($event.target.checked, item)"
                [checked]="checked(item)"
              >
                {{item}}
              </div>
              

              app.component.ts:

                options = ["1", "2", "3", "4", "5"]
                selected = ["1", "2", "5"]
              
                // check if the item are selected
                checked(item){
                  if(this.selected.indexOf(item) != -1){
                    return true;
                  }
                }
              
                // when checkbox change, add/remove the item from the array
                onChange(checked, item){
                  if(checked){
                  this.selected.push(item);
                  } else {
                    this.selected.splice(this.selected.indexOf(item), 1)
                  }
                }
              

              DEMO

              【讨论】:

                【解决方案12】:

                Angular 2+ 到 9 中使用 Typescript

                来源Link

                我们可以使用一个对象来绑定多个Checkbox

                  checkboxesDataList = [
                    {
                      id: 'C001',
                      label: 'Photography',
                      isChecked: true
                    },
                    {
                      id: 'C002',
                      label: 'Writing',
                      isChecked: true
                    },
                    {
                      id: 'C003',
                      label: 'Painting',
                      isChecked: true
                    },
                    {
                      id: 'C004',
                      label: 'Knitting',
                      isChecked: false
                    },
                    {
                      id: 'C004',
                      label: 'Dancing',
                      isChecked: false
                    },
                    {
                      id: 'C005',
                      label: 'Gardening',
                      isChecked: true
                    },
                    {
                      id: 'C006',
                      label: 'Drawing',
                      isChecked: true
                    },
                    {
                      id: 'C007',
                      label: 'Gyming',
                      isChecked: false
                    },
                    {
                      id: 'C008',
                      label: 'Cooking',
                      isChecked: true
                    },
                    {
                      id: 'C009',
                      label: 'Scrapbooking',
                      isChecked: false
                    },
                    {
                      id: 'C010',
                      label: 'Origami',
                      isChecked: false
                    }
                  ]
                

                在 HTML 模板中使用

                  <ul class="checkbox-items">
                    <li *ngFor="let item of checkboxesDataList">
                      <input type="checkbox" [(ngModel)]="item.isChecked" (change)="changeSelection()">{{item.label}}
                    </li>
                  </ul>
                

                要获得选中的复选框,请在类中添加以下方法

                  // Selected item
                  fetchSelectedItems() {
                    this.selectedItemsList = this.checkboxesDataList.filter((value, index) => {
                      return value.isChecked
                    });
                  }
                
                  // IDs of selected item
                  fetchCheckedIDs() {
                    this.checkedIDs = []
                    this.checkboxesDataList.forEach((value, index) => {
                      if (value.isChecked) {
                        this.checkedIDs.push(value.id);
                      }
                    });
                  }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2017-09-11
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-01-23
                  • 1970-01-01
                  • 2020-10-13
                  • 2015-02-11
                  • 1970-01-01
                  相关资源
                  最近更新 更多