即使模型更改,Angular 4 复选框状态也不会更新

Posted

技术标签:

【中文标题】即使模型更改,Angular 4 复选框状态也不会更新【英文标题】:Angular 4 checkbox state not updated even if model changed 【发布时间】:2018-04-07 11:14:52 【问题描述】:

我知道这个问题仍然存在,但根据这个解决方法Angular 2 - Checkbox not kept in sync 它应该可以按预期工作,但是我仍然很难让它适用于我的案例。

我有授予角色的权限列表。当用户想要更新角色时,我会显示带有可编辑角色名称的表单及其权限列表作为复选框列表。现在,如果角色已经拥有列表中的权限,我需要检查一些列表项。

我的表格:

<tr *ngFor ="let perm of permissions, let i = index">
        <td>
            <label>
            <input type="checkbox" 
                    name="check-box-perm.permission_alias"                                            
                    value="perm.permission_id"  
                    (ngModel)="perm.checked"
                    (ngModelChange)="onSelectFilter($event,perm)"
                    attr.id="check-box-perm.permission_alias"
                    /> 
            perm.permission_alias
            </label>                                
        </td>
    </tr>

我的组件:

getPermissions(role: Role): void 
    this.permissions = [];
    this.userService.getPermissions().then(perms =>             
        if (role != null) 
            this.permissions = perms;
            for (let rp of role.permissions)           
                let index = this.permissions.indexOf(this.permissions.find(p => p.permission_id == rp.permission_id));
                if (index >= 0)   
                     this.permissions[index].checked = true;
                    //this.onSelectFilter(true, this.permissions[index]); not sure if this should be called
                      
            
            console.log("before selected perms on update");
            console.log(this.permissions);
        
        else 
            this.permissions = perms;
        

    ).catch(this.handleError);


   onSelectFilter(selected: boolean, filter: Permission) 
        filter.checked = selected;
        if (this.permissions.every(filter => !filter.checked)) 
            setTimeout(() => 
                this.permissions.forEach(filter => filter.checked = true);
            );
        
    

我不知道为什么这不起作用,我没有在列表中选中任何项目。 如有任何帮助,我将不胜感激。

【问题讨论】:

哪一部分不工作。这段代码this.permissions.forEach(filter =&gt; filter.checked = true); 看起来很奇怪。您使用过滤器,但忽略结果,因为您正在使用分配的过滤条件。 setTimeout 看起来也很多余。 【参考方案1】:

我认为这里的错误是因为你总是'改变数组'。当 angular 运行变化检测时,它没有看到任何变化,并且 ngFor 没有更新。试试这段代码,看看我唯一要做的就是在对数组进行变异之前复制它。

getPermissions(role: Role): void 
this.permissions = [];
this.userService.getPermissions().then(perms =>             
    if (role != null) 
        this.permissions = perms;
        for (let rp of role.permissions)           
            let index = this.permissions.indexOf(this.permissions.find(p => p.permission_id == rp.permission_id));
            if (index >= 0)   
                 this.permissions = this.permissions.slice(0) // copy the array.
                 this.permissions[index].checked = true;
                //this.onSelectFilter(true, this.permissions[index]); not sure if this should be called
                  
        
        console.log("before selected perms on update");
        console.log(this.permissions);
    
    else 
        this.permissions = perms;
    

).catch(this.handleError);


   onSelectFilter(selected: boolean, filter: Permission) 
    filter.checked = selected;
    if (this.permissions.every(filter => !filter.checked)) 
        setTimeout(() => 
            this.permissions = this.permissions.slice(0) // copy the array.
            this.permissions.forEach(filter => filter.checked = true);
        );
    

【讨论】:

感谢您的回复,我已尝试应用您的更改,但没有帮助。我认为模型还可以,因为如果我在列表标签​​中显示perm.checked,我可以看到有些元素是真的,有些是假的。问题在于更新复选框状态。【参考方案2】:

这行得通。它将始终使用 2-way 数据绑定保持同步。

<input type="checkbox" 
name="check-box-filter.text"
[(ngModel)]="filter.selected"
attr.id="check-box-filter.text">

如果您需要在更改时触发某些功能,请使用更改事件。

<input type="checkbox" 
name="check-box-filter.text"
[(ngModel)]="filter.selected"'
(change)="myCustomFun()"
attr.id="check-box-filter.text">

从您的解决方法链接更新您的plunk 中的相同内容

【讨论】:

知道了,问题出在这行 `value="perm.permission_id" `,我需要删除它。无论如何,谢谢! 我喜欢这个解决方案,但我所尝试的结果却令人失望。所以解决方案是创建一个PromisesetTimeout 200 ms 来检查执行操作后检查的项目。【参考方案3】:

请使用 [(ngModel)] 和布尔变量,因为复选框是两种数据绑定方式

【讨论】:

一些解释为什么这有资格作为解决方案是好的。

以上是关于即使模型更改,Angular 4 复选框状态也不会更新的主要内容,如果未能解决你的问题,请参考以下文章

即使在状态更改后组件也不会更新

即使调用了渲染函数中的 console.log,组件也不会在状态更改时重新渲染

在Angular 5的子组件中与@Input绑定时,复选框的选中状态不会更新

Angular 4 - 如何让我的复选框更改变量的值?

Angular 2组件模型刷新视图,无需模型更改

如何检索动态框值(如果选中,则为真或假) - Angular 6