在标记选项的同一行的 td 中加载数据
Load data in a td of the same row where an option is marked
为了演示这个问题,我有一个 table,其中显示了详细信息列表和几个 mat-select
,当 select 选择一个选项时,它的“大小”标记的选项在 td 中加载。
问题是它不会在 selected 选项所在的同一行中加载“大小”。我怎么能得到这个?尺寸显示在 td 中,但按从上到下的顺序排列。
例如,如果没有标记的选项,我 select 第 3 行的一个选项。该选项的“大小”将加载到第一行,如果我在任何其他行标记一个选项数据按照行的顺序加载。
我在 stackblitz 中有演示:DemoStackblitz
HTML
<table class="table">
<tr>
<th>Titles</th>
<th>Size</th>
<th>Detail</th>
<th>Duration</th>
</tr>
<tr *ngFor="let row of dataDetails let i = index">
<td>
<mat-form-field appearance="outline">
<mat-select [formControl]="dataCtrl" placeholder="Select" [compareWith]="compareItems" #singleSelect>
<mat-option>
<ngx-mat-select-search [formControl]="dataFilterCtrl"></ngx-mat-select-search>
</mat-option>
<mat-option *ngFor="let op of filteredData | async" [value]="op.id" (click)="onSelect(op)"
[disabled]="op.condition===1">
{{op.title}}
</mat-option>
</mat-select>
</mat-form-field>
</td>
<td>{{OptionSelected[i]?.size}}</td>
<td>{{row.detail}}</td>
<td>{{row.duration}}</td>
</tr>
</table>
TS
dataTitles: any = DataTitles;
dataDetails: any = DataDetails;
dataCtrl: FormControl = new FormControl();
dataFilterCtrl: FormControl = new FormControl();
filteredData: ReplaySubject<any> = new ReplaySubject<any>(1);
@ViewChild('singleSelect', { static: true }) singleSelect: MatSelect;
_onDestroy = new Subject<void>();
ngOnInit() {
this.dataCtrl.setValue(this.dataDetails[0]);
this.filteredData.next(this.dataTitles.slice());
this.dataFilterCtrl.valueChanges
.pipe(takeUntil(this._onDestroy))
.subscribe(() => {
this.filterData();
});
}
compareItems(i1: any, i2: any) {
return i1 && i2 && i1.key === i2.key;
}
ngOnDestroy() {
this._onDestroy.next();
this._onDestroy.complete();
}
OptionSelected: any = [];
onSelect(option: any) {
var objIndex = this.dataTitles.findIndex(x => x.id == option.id);
if (this.dataTitles[objIndex].title !== 'None') {
this.dataTitles[objIndex].condition = 1;
}
if (this.OptionSelected.length === 0) {
this.OptionSelected.push({ id: option.id, size: option.size });
} else {
let check = this.OptionSelected.map((item: any) => item.id).includes(
option.id
);
if (check === false) {
this.OptionSelected.push({ id: option.id, size: option.size });
}
}
console.log(this.OptionSelected);
}
filterData() {
if (!this.dataTitles) {
return;
}
let search = this.dataFilterCtrl.value;
if (!search) {
this.filteredData.next(this.dataTitles.slice());
return;
} else {
search = search.toLowerCase();
}
this.filteredData.next(
this.dataTitles.filter(
(x: any) => x.title.toLowerCase().indexOf(search) > -1
)
);
}
问题
您在调用期间将当前选择的值推入 OptionSelected
onSelect
。这会导致所选行数据与实际显示数据的行不匹配。
伪代码示例:
Select TitleA in Row 4
Push new Data into OptionSelected
OptionSelected[0]?.size displays data in the first row
解决方案
您已经在此处使用模板变量 #singleSelect
跟踪当前所选值的值:
<mat-select ... #singleSelect>
<mat-select>
组件有一个值输入。
@Input()
value: any Value of the select control.
因此您可以通过简单地使用模板 ref 来显示当前值:
<td>{{singleSelect.value}}</td>
为了演示这个问题,我有一个 table,其中显示了详细信息列表和几个 mat-select
,当 select 选择一个选项时,它的“大小”标记的选项在 td 中加载。
问题是它不会在 selected 选项所在的同一行中加载“大小”。我怎么能得到这个?尺寸显示在 td 中,但按从上到下的顺序排列。
例如,如果没有标记的选项,我 select 第 3 行的一个选项。该选项的“大小”将加载到第一行,如果我在任何其他行标记一个选项数据按照行的顺序加载。
我在 stackblitz 中有演示:DemoStackblitz
HTML
<table class="table">
<tr>
<th>Titles</th>
<th>Size</th>
<th>Detail</th>
<th>Duration</th>
</tr>
<tr *ngFor="let row of dataDetails let i = index">
<td>
<mat-form-field appearance="outline">
<mat-select [formControl]="dataCtrl" placeholder="Select" [compareWith]="compareItems" #singleSelect>
<mat-option>
<ngx-mat-select-search [formControl]="dataFilterCtrl"></ngx-mat-select-search>
</mat-option>
<mat-option *ngFor="let op of filteredData | async" [value]="op.id" (click)="onSelect(op)"
[disabled]="op.condition===1">
{{op.title}}
</mat-option>
</mat-select>
</mat-form-field>
</td>
<td>{{OptionSelected[i]?.size}}</td>
<td>{{row.detail}}</td>
<td>{{row.duration}}</td>
</tr>
</table>
TS
dataTitles: any = DataTitles;
dataDetails: any = DataDetails;
dataCtrl: FormControl = new FormControl();
dataFilterCtrl: FormControl = new FormControl();
filteredData: ReplaySubject<any> = new ReplaySubject<any>(1);
@ViewChild('singleSelect', { static: true }) singleSelect: MatSelect;
_onDestroy = new Subject<void>();
ngOnInit() {
this.dataCtrl.setValue(this.dataDetails[0]);
this.filteredData.next(this.dataTitles.slice());
this.dataFilterCtrl.valueChanges
.pipe(takeUntil(this._onDestroy))
.subscribe(() => {
this.filterData();
});
}
compareItems(i1: any, i2: any) {
return i1 && i2 && i1.key === i2.key;
}
ngOnDestroy() {
this._onDestroy.next();
this._onDestroy.complete();
}
OptionSelected: any = [];
onSelect(option: any) {
var objIndex = this.dataTitles.findIndex(x => x.id == option.id);
if (this.dataTitles[objIndex].title !== 'None') {
this.dataTitles[objIndex].condition = 1;
}
if (this.OptionSelected.length === 0) {
this.OptionSelected.push({ id: option.id, size: option.size });
} else {
let check = this.OptionSelected.map((item: any) => item.id).includes(
option.id
);
if (check === false) {
this.OptionSelected.push({ id: option.id, size: option.size });
}
}
console.log(this.OptionSelected);
}
filterData() {
if (!this.dataTitles) {
return;
}
let search = this.dataFilterCtrl.value;
if (!search) {
this.filteredData.next(this.dataTitles.slice());
return;
} else {
search = search.toLowerCase();
}
this.filteredData.next(
this.dataTitles.filter(
(x: any) => x.title.toLowerCase().indexOf(search) > -1
)
);
}
问题
您在调用期间将当前选择的值推入 OptionSelected
onSelect
。这会导致所选行数据与实际显示数据的行不匹配。
伪代码示例:
Select TitleA in Row 4
Push new Data into OptionSelected
OptionSelected[0]?.size displays data in the first row
解决方案
您已经在此处使用模板变量 #singleSelect
跟踪当前所选值的值:
<mat-select ... #singleSelect>
<mat-select>
组件有一个值输入。
@Input()
value: any Value of the select control.
因此您可以通过简单地使用模板 ref 来显示当前值:
<td>{{singleSelect.value}}</td>