我有三个组件-组件A,组件B和组件C。组件A包装了组件B。组件B包装了组件C。如果我在每个组件中使用@Input(),则会更改根组件传递中的选项通过嵌套的组件到组件C?见下文:
<component-a [options]="options">
<component-b [options]="options">
<component-c [options]="options">
</component-c>
</component-b>
</component-a>
我问这个问题是因为当选项在应用程序的根组件中更改时,我需要对每个嵌套组件进行一些过滤。但是,我注意到第三方组件似乎没有收到options
的某些异常行为?在回答了该问题的第一部分之后,我可以进一步阐述。
我相信问题的答案是“是”。这是第二部分。当组件包装如下时,如何更新<ng-select>
:
<component-a [options]="options">
<component-b [options]="options">
<ng-select [items]="options" [(ngModel)]="selectedOption">
</ng-select>
</component-b>
</component-a>
当<ng-select>
的文档中显示以下内容时:
更改检测
Ng-select组件实现OnPush变化检测,这意味着 脏检查检查不可变的数据类型。这意味着如果你这样做 对象突变,例如:
this.items.push({id: 1, name: 'New item'})
组件将不会检测到更改。相反,您需要这样做:
this.items = [...this.items, {id: 1, name: 'New item'}];
这将使组件检测到更改并更新。一些 可能会担心这是一项昂贵的操作,但是, 比运行ngDoCheck并不断扩散差异要好得多 数组。
那么如何确保对options
的更改反映在<ng-select>
中?
答案 0 :(得分:2)
我有一个解决方法。由于您的选项是一个对象,角度不会检测到该对象的更改。您需要更改对象的参考,以便角度对更改进行反作用
下面是将起作用的代码,您进行更改检测将如预期那样
this.options = Object.assign({},this.options)
以上代码将更改对象的引用,从而触发更改检测
答案 1 :(得分:0)
是的,您可以通过这种方式将@Input参数向下传递给多个组件。我不知道有关ng-select的问题的答案,但是在component.ts文件中,您可以使用ngOnChanges生命周期钩子来检测@Input值何时更改。这是一篇不错的文章:https://ngdev.space/angular-2-input-property-changes-detection-3ccbf7e366d2
答案 2 :(得分:0)
尽管我喜欢@ renil-babu进行变异,但最终我还是决定使用<ng-option>
模板和*ngFor
。
<ng-select [id]="name"
[attr.name]="name"
[placeholder]="placeholder">
<ng-option *ngFor="let input of options" [value]="input.value">
{{ input.text }}
</ng-option>
</ng-select>
更新:不幸的是,这不起作用,因为在更改选项时不接受传递的变量
最终的实现需要不变性和(add)事件来触发它。
<ng-select
[items]="items"
[multiple]="true"
(add)="exclude($event, items)"
[(ngModel)]="selected">
</ng-select>
<br>
<ng-select
[items]="items2"
[multiple]="true"
(add)="exclude($event, items2)"
[(ngModel)]="selected2">
</ng-select>
<br>
<ng-select
[items]="items3"
[multiple]="true"
(add)="exclude($event, items3)"
[(ngModel)]="selected3">
</ng-select>
这是打字稿:
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
selected;
selected2;
selected3;
items: string[];
items2: string[];
items3: string[];
all :any[];
ngOnInit() {
this.items = ['Vilnius', 'Kaunas', 'Klaipeda'];
this.items2 = [...this.items];
this.items3 = [...this.items];
this.all = [this.items, this.items2, this.items3];
}
exclude(item, currentArray) {
for (let i = 0; i < 3; i++) {
const items = this.all[i];
if (items !== currentArray) {
this.all[i] = items.filter(x => x !== item);
}
}
this.items = this.all[0];
this.items2 = this.all[1];
this.items3 = this.all[2];
}
}