Angular select 选项控件不会自动重置 ngModel 值,即使我清空了选项数组
Angular select options control does not reset ngModel value automatically even if I empty the array of options
我在 Angular 8 中有一个非常基本的 select 选项输入控件。用户 select 从下拉列表中选择了一项,它在下拉列表和 ngModel
变量。
但是,如果我以编程方式清空源数组,下拉菜单仍将旧值保留在 ngModel
中,并且 angular 验证显示控件处于 "valid" 状态。但是,由于源数组现在为空,因此下拉列表中没有显示 selected。
我希望 ngModel
应该被重置并且控件应该处于无效状态,因为现在什么都没有 selected。
我的期望错了吗?还是我做错了什么?
以下是重现该行为的完整示例:
Angular 8: StackBlitz
更新 1:
我在 Angular 1 中创建了一个示例,它完全按照我的预期工作。 Angular如果在选项数组中找不到匹配的选项,JS 会清除模型值。我的观点是,如果下拉菜单是空的,那么用户会认为没有 selected。然而,在 Angular2+ 的情况下,它在幕后持有旧模型值。
Angular 1: StackBlitz
要清空 selection 的模型和选项数组设置不同,您必须重置或将 ngModel 设置为空白或“”。因为 selection 设置了 ngModel 值,但它没有 link 数组,所以 ngModel 包含设置给它的值。当您删除数组时,select 的值不存在,因为它是对值数组的引用,其中 ngModel 不引用数组,而是通过下拉
设置的值
它工作正常。
为什么您希望更改数组时也会更改与其对应的下拉键模型?模型可以绑定到不包含其值的下拉列表。您不能 select 该值,但模型不会变为空,因为该值不在下拉列表的值中。
您需要手动将模型的值设置为您想要的值。
在你的 Angular 1 stackblitz 中,如果你给模型一个默认值,它不会被清除数组清除 https://stackblitz.com/edit/angularjs-yia6a4?file=home/home.controller.js
我认为你的期望有问题,不需要清空下拉列表。只需要像这样 model.power = ''
将 ngModel
设置为空值。
因此,由于您在这里使用的是模板驱动表单,因此您也可以通过使用表单 (heroForm
) 的 reset()
方法重置表单状态,如下所示,无需更改任何内容:
<button type="button" class="btn btn-default" (click)="heroForm.reset()">Clear Array</button>
如果您需要清空下拉列表并且还需要将表单状态设置为无效状态,请像下面这样使用
<button type="button" class="btn btn-default" (click)="powers=[]; model.power=''">Clear Array</button>
根据你更新的问题,你可以像下面这样实现它:
<div class="form-group">
<label for="power">Hero Power</label>
<select class="form-control" id="power"
required
[(ngModel)]="model.power" name="power"
#power="ngModel">
<option [ngValue]="null">All</option>
<option *ngFor="let pow of powers" [ngValue]="pow">{{pow}}</option>
</select>
</div>
<button type="button" class="btn btn-default" (click)="powers=[]; model.power=null">Clear Array</button>
//suppose in app.component.html you have select list of agent, it works for me.
<ng-select [multiple]="true" #chooseAgent
(selected)="selected($event)"
(removed)="removed($event)" *ngIf="agentLists" [items]="agentLists" bindLabel="name" bindValue="id" >
</ng-select>
and i have a reset button to reset the select list.
<button type="button" class="btn btn-themegreen" (click)="Cancel()">Reset</button>
//in app.component.ts
import { Component, OnInit, ViewChild, Input, Output, EventEmitter } from '@angular/core';
import { NgSelectComponent } from '@ng-select/ng-select';
//define variable.
@ViewChild('chooseAgent', {static:false})
ngSelectComponentAgent!: NgSelectComponent;
agentLists: any[] = [];
Cancel(){
this.ngSelectComponentAgent.handleClearClick();
this.agentLists.length=0;
}
像下面这样尝试,
HTML
<button type="button" class="btn btn-default" (click)="clearArray(heroForm)">Clear Array</button>
组件
clearArray(form: FormGroup) {
this.powers=[];
form.reset();
}
如果您只想重置电源,
form.controls.power.reset();
我在 Angular 8 中有一个非常基本的 select 选项输入控件。用户 select 从下拉列表中选择了一项,它在下拉列表和 ngModel
变量。
但是,如果我以编程方式清空源数组,下拉菜单仍将旧值保留在 ngModel
中,并且 angular 验证显示控件处于 "valid" 状态。但是,由于源数组现在为空,因此下拉列表中没有显示 selected。
我希望 ngModel
应该被重置并且控件应该处于无效状态,因为现在什么都没有 selected。
我的期望错了吗?还是我做错了什么?
以下是重现该行为的完整示例:
Angular 8: StackBlitz
更新 1:
我在 Angular 1 中创建了一个示例,它完全按照我的预期工作。 Angular如果在选项数组中找不到匹配的选项,JS 会清除模型值。我的观点是,如果下拉菜单是空的,那么用户会认为没有 selected。然而,在 Angular2+ 的情况下,它在幕后持有旧模型值。
Angular 1: StackBlitz
要清空 selection 的模型和选项数组设置不同,您必须重置或将 ngModel 设置为空白或“”。因为 selection 设置了 ngModel 值,但它没有 link 数组,所以 ngModel 包含设置给它的值。当您删除数组时,select 的值不存在,因为它是对值数组的引用,其中 ngModel 不引用数组,而是通过下拉
设置的值它工作正常。
为什么您希望更改数组时也会更改与其对应的下拉键模型?模型可以绑定到不包含其值的下拉列表。您不能 select 该值,但模型不会变为空,因为该值不在下拉列表的值中。
您需要手动将模型的值设置为您想要的值。
在你的 Angular 1 stackblitz 中,如果你给模型一个默认值,它不会被清除数组清除 https://stackblitz.com/edit/angularjs-yia6a4?file=home/home.controller.js
我认为你的期望有问题,不需要清空下拉列表。只需要像这样 model.power = ''
将 ngModel
设置为空值。
因此,由于您在这里使用的是模板驱动表单,因此您也可以通过使用表单 (heroForm
) 的 reset()
方法重置表单状态,如下所示,无需更改任何内容:
<button type="button" class="btn btn-default" (click)="heroForm.reset()">Clear Array</button>
如果您需要清空下拉列表并且还需要将表单状态设置为无效状态,请像下面这样使用
<button type="button" class="btn btn-default" (click)="powers=[]; model.power=''">Clear Array</button>
根据你更新的问题,你可以像下面这样实现它:
<div class="form-group">
<label for="power">Hero Power</label>
<select class="form-control" id="power"
required
[(ngModel)]="model.power" name="power"
#power="ngModel">
<option [ngValue]="null">All</option>
<option *ngFor="let pow of powers" [ngValue]="pow">{{pow}}</option>
</select>
</div>
<button type="button" class="btn btn-default" (click)="powers=[]; model.power=null">Clear Array</button>
//suppose in app.component.html you have select list of agent, it works for me.
<ng-select [multiple]="true" #chooseAgent
(selected)="selected($event)"
(removed)="removed($event)" *ngIf="agentLists" [items]="agentLists" bindLabel="name" bindValue="id" >
</ng-select>
and i have a reset button to reset the select list.
<button type="button" class="btn btn-themegreen" (click)="Cancel()">Reset</button>
//in app.component.ts
import { Component, OnInit, ViewChild, Input, Output, EventEmitter } from '@angular/core';
import { NgSelectComponent } from '@ng-select/ng-select';
//define variable.
@ViewChild('chooseAgent', {static:false})
ngSelectComponentAgent!: NgSelectComponent;
agentLists: any[] = [];
Cancel(){
this.ngSelectComponentAgent.handleClearClick();
this.agentLists.length=0;
}
像下面这样尝试,
HTML
<button type="button" class="btn btn-default" (click)="clearArray(heroForm)">Clear Array</button>
组件
clearArray(form: FormGroup) {
this.powers=[];
form.reset();
}
如果您只想重置电源,
form.controls.power.reset();