-1

我有一个父组件,它使用 . 将一些数据 ( selectedId) 传递给子组件@Input()

父模板

<child-component [selectedId]="selectedId"></child-component>

子组件使用selectedId如下:

子模板

<select [(ngModel)]="selectedId">
  <option [value]="option.id" *ngFor="let option of options">{{option.name}}</option>
</select>

子组件

export class HelloComponent  {
  @Input()
    set selectedId(id: any) {
      this._selectedId = id;
  }
  get selectedId() {
    return this._selectedId;
  }

  public _selectedId;

  options = [
      {
        "id": "1",
        "name": "Weekly"
      },
      {
        "id": "2",
        "name": "Bi-Weekly"
      },
      {

        "id": "3",
        "name": "Lunar"
      },
      {
        "id": "4",
        "name": "Monthly"
      }
  ]
}

这完美地工作。问题是当我直接从子组件更改所选项目时 - 不使用父组件。

当它不能按预期工作时,这是以下情况:

  1. selectedId父组件(API 调用)填充
  2. 使用手动更改选择选项(从child-component
  3. API 再次被调用,它应该设置与步骤 1 中设置的 ID 相同的 ID。但是这不会触发更改事件。我的假设是父组件不知道在子组件中进行的手动更改,因此它仍然包含对selectedId步骤 1 的引用,并且不会触发步骤 3 中的更改,因为它是相同的 ID。

我在Stackblitz上重现了这个问题

我知道我可以使用Output()和共享服务来解决这个问题,但是有没有其他方法可以通知家长有关更改检测的信息?

4

2 回答 2

3

当子组件发生变化时,您可以使用它@Output来通知父组件


@Component({
  selector: 'hello',
  templateUrl: './hello.component.html',
  styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent  {
  @Input()
    set selectedId(id: any) {
      this._selectedId = id;
      console.log('Child change event --> ', id);
  }
  get selectedId() {
    return this._selectedId;
  }

  @Output() selectedIdChange=new EventEmitter();

  public _selectedId;

  options = [
      {
        "id": "1",
        "name": "Weekly"
      },
      {
        "id": "2",
        "name": "Bi-Weekly"
      },
      {
        "id": "3",
        "name": "Lunar"
      },
      {
        "id": "4",
        "name": "Monthly"
      }
  ]
  onChangeSelectedId(){
    this.selectedIdChange.emit(this.selectedId);
  }
}

并像这样设置值

<hello [(selectedId)]="selectedId"></hello>

于 2019-08-29T09:36:03.357 回答
2

方法 1:将此变量添加到共享服务并从那里使用它。每当孩子或父母修改它时,它都会更新。

方法 2:将输入从父组件传递给子组件并添加一个事件发射器,因此每当子组件中的值发生变化时,您应该发出一个事件以更新父组件中的值

于 2019-08-29T09:29:34.450 回答