Angular NgModel重新评估getter @Input

时间:2017-10-12 14:49:45

标签: angular angular-forms

我们正在开展一个角度项目,我们有一个组件可以生成一个通过getter加载的列表,该列表生成使用ngModel指令的输入。每当我们更改输入中的值时,项目列表会因某种原因重新评估,并重新呈现我们不想要的组件。

这是一个显示此行为的示例。

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

@Component({
  selector: 'my-app',
  template: `
    <div>
      <test-component [items]="getterList"></test-component>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class App implements OnChanges{
  staticList = ["a","b","c"];

  get getterList():string[]{
    console.log('getterList');
    return this.staticList.map(a=>a);
  }

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


@Component({
  selector: 'test-component',
  template: `
    <div *ngFor="let item of items">
        {{item}}
        <input type="text" [(ngModel)]="testValue" placeholder="ngModel" />
        <input type="text" [value]="testValue" placeholder="no ngModel" />
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class TestComponent {
  @Input() items:string[] = [];
  testValue:string="";
}


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

(这里是plunker) https://plnkr.co/edit/MigjRs3MULcNS55oKVpp?p=preview

在这个例子中,我们有一个通过getter生成的列表。列表的每个元素生成2个输入;一个使用ngModel ,另一个没有ngModel ,我们可以看到第二个输入不会触发getter。

为什么ngModel指令会重新触发getter?

1 个答案:

答案 0 :(得分:0)

嗯,那个捡拾者很有帮助。 [(ngModel)]语法用于双向绑定。在您的模板中,使用[(ngModel)]="testValue",它对于循环的每次迭代都是相同的(迭代元素是item(项目,根据*ngFor)。所以基本上所有“首先 - 输入“在循环中每次迭代都绑定到一个模型属性testValue。由于双向绑定,它会自动更新”第一个输入“字段的其余部分。第二个是[value]="testValue"仅使用[]这是一种单向绑定。因此它不会更新剩余的字段。

如果您从()移除[(ngModel)],使其变为单向绑定,[ngModel],则可以看到差异。它的行为与第二个输入字段非常相似。所以本质上它与你的吸气剂无关,所有的魔力都发生在双向[(ngModel)]绑定上。希望它有所帮助