2017-10-12 78 views
1

我们正在研究一个角度项目,其中我们有一个组件生成通过getter加载的列表,并且该列表生成使用ngModel指令的输入。每次我们改变输入值时,出于某种原因都重新评估项目列表,并重新渲染我们不想要的组件。Angular NgModel重新评估getter @Input

下面是一个显示此行为的示例。

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?

+0

这里的getter的用例是什么,你需要它来做什么? – Alex

+0

是的,我们从一个实体映射到另一个实体,我们知道我们可以在ngOnInit中做一次,但我们试图理解ngModel为什么会无缘无故地触发getter –

回答

0

那么,重拳者是有帮助的。 [(ngModel)]语法用于双向绑定。在你的模板中,你使用的是[(ngModel)]="testValue",它对于循环的每次迭代都是一样的(迭代的元素是item(按照*ngFor),所以基本上循环的每次迭代中的所有“第一次输入”都与一个model property testValue。由于双向绑定,它会自动更新其余的“第一个输入”字段,第二个是[value]="testValue",它只使用[]这是一个单向绑定,因此它不会更新剩余的字段。

如果您从[(ngModel)](),使之成为只是单向绑定这样,[ngModel],你可以看到其中的差别,它的行为很像第二个输入字段,所以在本质上它无关你的吸气者,全部魔术发生在2路[(ngModel)]绑定中。希望它有帮助

+0

问题不在于字段以及它如何应用于其他字段。问题是当ngModel改变时,列表的getter被回显。 –

+0

就像我说的,这是由于双向绑定语法。如果你只是简单地使用''[ngModel]'而不是'[(ngModel)]',它会被触发吗? – amal

+0

我们想要双重绑定,当我们改变字段时,我们不希望通过父级的(AppComponent)getter无故重建列表。 –