Angular 反应复选框仅在第一次单击后正确切换

Posted

技术标签:

【中文标题】Angular 反应复选框仅在第一次单击后正确切换【英文标题】:Angular reactive checkboxes only toggle correctly after first click 【发布时间】:2017-12-22 09:35:54 【问题描述】:

我有一个由复选框动态生成的表单,以及一个从服务器获取表单数据的初始 get 请求(哪些复选框被选中和未选中,由值 0 或 1 定义为真或假) 当我单击一个复选框时,它应该切换(选中/未选中)以及发送正确的 put 请求(与当前值相反(0 到 1、1 到 0)。 现在,所有未选中的复选框都按预期运行。但是从初始获取选中的框,单击一次,然后取消选中并在应该发送 0 时发送 1,如果再次单击,则保持未选中状态但发送正确的输出 0,然后该复选框从那时起正确运行.发生了什么导致第一次点击只有选中的框?

比较

places;
    ready = false;
    countriesForm: FormGroup;

constructor(private whiteListService: WhiteListService) 

ngOnInit() 
    // get places list with status'
    this.whiteListService.getList()
        .subscribe(
            (response: Response) => 
                console.log(response.statusText);
                this.places = response.json();
                this.createList(this.places.countries);
            ,
            (error) => console.log(error)
        );


createList(places) 
    // assign this.places for dom binding access
    this.places = places;
    console.log(places)
    this.countriesForm = new FormGroup();
    for (let i = 0; i < this.places.length; i++) 
        this.countriesForm.addControl(
            this.places[i].name, new FormControl()
        );
    
    this.ready = true;


toggleAllowed(place, event) 
    // send authorization of country to server
    console.log('allow before switch', place.allow);
    place.allow === 1 ? place.allow = 0 : place.allow = 1;
    console.log('allow after switch', place.allow);
    console.log(this.places);
    this.whiteListService.sendAllow(place.code, place.allow)
        .subscribe(
            (response) => console.log(response),
            (error) => 
                console.log(error);
                place.allow = !place.allow;
            
        );

html

<div class="geo-list">
    <div class="content-box container">
         <form *ngIf="ready" [formGroup]="countriesForm">
            <div class="place" *ngFor="let place of places">
                <input
                    type="checkbox"
                    formControlName="place.name"
                    value="place.allow"
                    (change)="toggleAllowed(place, $event)"
                    [checked]="place.allow == 1"
                >
                 place.name  |  place.code  |  place.continent  |  place.allow 
            </div>
        </form>
    </div>
</div>

【问题讨论】:

【参考方案1】:

您需要为表单控件设置值,因为现在无论是否选中该框,表单控件的值最初都是null

我们可以通过在您的迭代中解决此问题,您可以根据数值将值设置为 truefalse

for (let i = 0; i < this.places.length; i++) 
  this.countriesForm.addControl(
     this.places[i].name, new FormControl(this.places[i].allow == 1 ? true : false)
  );

然后你可以去掉模板中的checked

<input
   type="checkbox"
   formControlName="place.name"
   (change)="toggleAllowed(place, $event)"
>

作为旁注,理论上你不需要在truefalse 之间切换01,正如这里所说:Is true == 1 and false == 0 in javascript? 但我会坚持使用@987654333 @ 和 false :)

【讨论】:

感谢@AJT_82,我实施了建议的更改,但现在每个复选框总是将第一次点击发送为值 1。即使是已经选中的框。这让我很困惑。作为旁注,我从 ts lint 收到关于双等号的警告,显然三等号不起作用。为什么是这样?为什么将 FormControlValue 设置为 this.places[i].allow 不起作用? 不太清楚你对 的意思,但现在每个复选框总是将第一次点击发送为值 1。?我无法重现:plnkr.co/edit/8S4wrBu0JBG5M4MlpcuP?p=preview 和 === 检查 type 和 value,至于 == 只检查 value。 我的意思是当 get 返回列表的当前状态时,一些值设置为 0,一些设置为 1,当添加你的方法时,即使 get 请求返回一个 1 复选框,然后我单击该框以取消选中它,它发送一个 1,而不是一个 0。但我发现了我的问题,如下所述,感谢您的帮助【参考方案2】:

好的,所以我解决了这个问题,通过更改 toggleAllowed 函数中的开关函数使用“==”而不是“===”。而 ts lint 对此进行标记并建议 '===' 它不能与 '===' 一起使用。不知道为什么。

此方法适用于预定义控件值,或使用 [check]="place.allow" 定义它们。

【讨论】:

以上是关于Angular 反应复选框仅在第一次单击后正确切换的主要内容,如果未能解决你的问题,请参考以下文章

反应复选框不切换

根据最初检查的复选框值在后退按钮单击时重新加载 Angular 6 反应式表单

jQuery 在第一次切换后仅在 Safari iOS5 中单击 3 次后触发

UIButton 切换标题。仅在第二次单击后更改

单击功能后在表格中切换复选框

如何仅在输入模糊时触发反应表单 valueChanges 订阅并在 Angular 2 中输入键