【问题标题】:Function ngOnChanges() is not working in Angular 5函数 ngOnChanges() 在 Angular 5 中不起作用
【发布时间】:2018-07-17 04:08:52
【问题描述】:

每当组件生命周期或模板中的变量 this.test 发生更改但它不起作用时,我试图在我的 Angular 5.x 组件中调用函数 ngOnChanges() 但它不起作用,ngOnChanges() 函数不会随时调用。请问有人可以帮我吗?

src/app.ts:

import {Component, NgModule, Input, OnChanges, SimpleChanges} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'

@Component({
  selector: 'my-app',
  template: `
    <div>
      <input type="text" placeholder="Test field" value="{{ test }}">
    </div>
  `,
})
export class App implements OnChanges {
  @Input() test: string;
  name: string;
  constructor() {
  }

  ngOnChanges(changes: SimpleChanges) {
    console.log('ngOnChanges');

    if (changes.test && !changes.test.isFirstChange()) {
      // exteranl API call or more preprocessing...
    }

    for (let propName in changes) {
      let change = changes[propName];
      console.dir(change);
      if(change.isFirstChange()) {
        console.log(`first change: ${propName}`);
      } else {
        console.log(`prev: ${change.previousValue}, cur: ${change.currentValue}`);
      }
    }
  }


}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}

实时预览:https://plnkr.co/edit/ZHFOXFhEkSv2f1U3lehv

非常感谢!

【问题讨论】:

  • 我在您的链接插件中看到模板解析错误。它不喜欢你的 ngModel 用法

标签: javascript angular typescript ngonchanges


【解决方案1】:

输入属性为父组件提供了一种将数据传递给子组件的机制。它们并不意味着将数据从模板传递到其组件。

只有对 PARENT 定义的输入属性的更改才会生成 onChanges 方法。

我更新了 plunker 以修复丢失的 FormsModule 并添加了一个子组件来演示如何使用 input 属性和 onChanges 生命周期钩子:

https://plnkr.co/edit/1JF0wV28HnjXDZxMSifY?p=preview

子组件

@Component({
  selector: 'my-child',
  template: `
    <div>
      <input type="text" [(ngModel)]="test" placeholder="Test field">
    </div>
  `,
})
export class ChildComponent implements OnChanges {
  @Input() test: string;
  name: string;
  constructor() {  }

  ngOnChanges(changes: SimpleChanges) {
    console.log('in ngOnChanges');
    if (changes.test && !changes.test.isFirstChange()) {
      // exteranl API call or more preprocessing...
    }

    for (let propName in changes) {
      let change = changes[propName];
      console.dir(change);
      if(change.isFirstChange()) {
        console.log(`first change: ${propName}`);
      } else {
        console.log(`prev: ${change.previousValue}, cur: ${change.currentValue}`);
      }
    }
  }
}

父组件

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <my-child [test]='parentTest'></my-child>
      <button (click)='onClick()'>Change Value</button>
    </div>
  `,
})
export class App {
  parentTest: string;
  name: string;
  counter = 1;

  constructor() {
    this.name = `Angular! v${VERSION.full}`
  }

  onClick() {
    this.parentTest = `test: ${this.counter}`;
    this.counter++;
  }
}

要在模板组件中捕获来自模板的更改,请改用 setter:

  // To catch changes from the template
  _test: string;
  get test(): string {
    return this._test;
  }

  @Input()
  set test(value: string) {
    this._test = value;
    console.log("Textbox value changed: " + this._test);
  }

或者您可以使用 Sajeetharan 的建议来捕捉模板在其关联模板中的更改。它也会起作用。

【讨论】:

    【解决方案2】:

    你需要的是 ngModelChange 而不是 ngOnChanges

    <input type="text" placeholder="Test field" (ngModelChange)="printVal()">
    

    然后

    printVal(){
      //detect model change here
    }
    

    ngOnChanges 作用于@input 事件发射器

    【讨论】:

    猜你喜欢
    • 2018-10-14
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    • 2018-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-10
    相关资源
    最近更新 更多