简体   繁体   English

如何在Angular2中触发模型更改事件?

[英]How do I trigger an event on model change in Angular2?

I would like to build a drum machine in Angular2 similar to an existing Angular project. 我想在Angular2中构建一个类似于现有 Angular项目的鼓机

The way I have structured the components is to have a SequencerComponent (parent) that emits an event (@Output) at a specified interval (BPM). 我构建组件的方法是让SequencerComponent(父级)以指定的间隔(BPM)发出事件(@Output)。

// sequencer.component.ts
@Output() metronome = new EventEmitter();

  onBeat(count: number) {
    if(this.isPlaying) {
      this.beat.one = count == 1;
      this.beat.two = count == 2;
      this.beat.three = count == 3;
      this.beat.four = count == 4;

      this.metronome.emit(this.beat);
    }
  }

PadsComponent (child) listens to this event (@Input) and should then play a sound if a PadComponent (grand-child) is set to active. PadsComponent(child)侦听此事件(@Input),然后如果PadComponent(grand-child)设置为active,则应播放声音。

// pads.component.ts
export class PadsComponent {
  @Input() hit: any = {};
}

// pads.component.html
<pad [class.active]="hit.one" class="column pad"></pad>

<pad [class.active]="hit.two" class="column pad"></pad>

<pad [class.active]="hit.three" class="column pad"></pad>

<pad [class.active]="hit.four" class="column pad"></pad>

I can get the classes to change but obviously I want to do more than HTML attribute binding. 我可以让类改变,但显然我想做的不仅仅是HTML属性绑定。 Working example 工作实例

How can I get the child and grand-child to run a function on model change? 如何让孩子和大孩子在模型改变中运行功能? And is there a better, more idiomatic way to solve this problem? 是否有更好,更惯用的方法来解决这个问题?

I have tried using ngDoCheck but I haven't discovered how to use it in this use case. 我尝试过使用ngDoCheck但我还没有发现如何在这个用例中使用它。

Update : hit is being bound to the beat in sequencer.component.html like so: 更新hitsequencer.component.htmlbeat绑定如下:

<!-- sequencer.component.html -->
<div class="columns">
  <div class="column">
    <a class="button is-success" (click)="onPlay($event)" href="">Play</a>

    <a class="button is-danger" (click)="onStop($event)" href="">Stop</a>
  </div>
</div>

<pads [hit]="beat"></pads>

Instead of @Input() hit: any = {}; 而不是@Input() hit: any = {}; you can have a getter and a setter for hit : 你可以有一个getter和一个setter for hit

private _hit;  // define a private variable _hit

@Input()
set hit(hit:any){  
    this._hit = hit;  // set the private variable and do whatever you want after each change
    playSomeSound(hit);
}
get hit(){  
    return this._hit;
}

Your template code is still the same, 您的模板代码仍然相同,

<pad [class.active]="hit.one" class="column pad"></pad>
...

check this plunk for an example. 请查看此插件以获取示例。

Here's an example of how to use ngDoCheck() to watch for model change and emit it: 以下是如何使用ngDoCheck()监视模型更改并将其发出的示例:

ngDoCheck() {

  if (this.previousModel !== this.model) {
    this.modelChange.emit(this.model);
  }

  this.previousModel = this.model;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM