2017-10-12 64 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無故重建列表。 –