角度:使用@Input()传递数据

时间:2018-08-13 00:58:57

标签: javascript angular nested angular6

我有三个组件-组件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>中?

3 个答案:

答案 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];
  }
}