Ng-Select多表单下拉框联动赋值问题
嘿,看起来你在实现Ng-Select多下拉框同步更新时遇到了卡点,我来帮你捋捋问题出在哪,以及怎么解决~
首先,咱们得先搞清楚你当前代码的核心问题:你现在的复用组件里,每个实例都维护着自己独立的selectedOption变量。所以当你在某个下拉框触发onSelect时,只是修改了当前组件的selectedOption,其他复用组件的这个变量并没有同步更新,自然也就不会跟着变啦。
那怎么让所有下拉框共享选中状态呢?核心思路是让所有下拉框绑定同一个全局的选中值源,通过父子组件的输入输出联动来同步。下面给你具体的修改步骤:
第一步:改造子组件(reusable-form.component.ts)
- 先添加输入输出属性,用来接收父组件的全局选中值,并且把自身的选择变化通知给父组件:
import { Component, Input, Output, EventEmitter, ChangeDetectorRef } from '@angular/core'; @Component({ selector: 'reusable-form', templateUrl: './reusable-form.component.html' }) export class ReusableFormComponent { @Input() selectedValue: string; // 接收父组件传入的全局选中值 @Output() selectedValueChange = new EventEmitter<string>(); // 向父组件发送选中变化事件 datas: any[]; // 你的下拉选项数据 constructor(private cdref: ChangeDetectorRef) {} // 定义trackBy方法(你原来的语法有问题,得单独定义) trackByUserByName(index: number, data: any): string { return data.name; } onSelect(event: string) { // 把选中值传给父组件,让父组件更新全局值 this.selectedValueChange.emit(event); // 必要时手动触发变更检测 this.cdref.detectChanges(); } }
- 同步修改子组件的模板:
<ng-select [searchable]="false" [clearable]="false" [ngModel]="selectedValue" (ngModelChange)="onSelect($event)" placeholder="search" > <ng-option *ngFor="let data of datas; trackBy: trackByUserByName" [value]="data.name" > {{ data.name }} </ng-option> </ng-select>
这里要注意:把原来的[(ngModel)]拆成单向绑定[ngModel]和(ngModelChange)事件,或者也可以用双向绑定语法[(selectedValue)]="selectedValue",不过分开写更清晰~另外你原来的trackBy:userByName语法错误,得改成调用定义好的trackByUserByName方法。
第二步:改造父组件
在父组件里维护一个全局的选中值,然后把它传给所有复用的子组件,同时监听子组件的变化事件来更新全局值:
import { Component } from '@angular/core'; @Component({ selector: 'app-parent', templateUrl: './parent.component.html' }) export class ParentComponent { // 全局选中值,所有下拉框共享这个值 globalSelectedOption: string; // 当任意一个下拉框选中变化时,更新全局值 updateAllDropdowns(value: string) { this.globalSelectedOption = value; } }
父组件模板里的用法:
<!-- 多个复用的表单组件,都绑定同一个全局选中值 --> <reusable-form [selectedValue]="globalSelectedOption" (selectedValueChange)="updateAllDropdowns($event)" ></reusable-form> <reusable-form [selectedValue]="globalSelectedOption" (selectedValueChange)="updateAllDropdowns($event)" ></reusable-form> <reusable-form [selectedValue]="globalSelectedOption" (selectedValueChange)="updateAllDropdowns($event)" ></reusable-form>
这样一来,不管你操作哪个下拉框,都会把选中值传给父组件的globalSelectedOption,而所有子组件都绑定了这个全局值,自然就会同步更新啦!
另外补充一点:如果你是用Angular的服务来共享状态,也是可行的思路——在服务里定义一个BehaviorSubject来保存选中值,所有子组件订阅这个Subject的变化,同时在选择变化时更新Subject的值。不过对于简单的场景,父子组件输入输出的方式已经足够好用啦。
备注:内容来源于stack exchange,提问作者Hari

