1. 程式人生 > >深入瞭解Angularjs指令中的 [(ngModel)]的實現原理

深入瞭解Angularjs指令中的 [(ngModel)]的實現原理

討論[(ngModel)]之前,先講下屬性繫結和事件繫結。 在屬性繫結中,值從模型中流動到檢視上的目標屬性。[],通過把屬性名放在方括號中來標記出目標屬性。這是從模型到檢視的單向資料繫結。 在事件繫結中,值從檢視上的目標屬性流動到模型。(),通過把屬性名放在圓括號中來標記出目標屬性。這是從檢視到模型的(反向的)單向資料繫結。 所以,組合[]和()就可以實現雙向資料繫結和雙向資料流。 事實上,我們也可以把NgModel繫結拆分成兩個獨立的繫結,屬性繫結和事件繫結。 eg: NgModel繫結
<input type="text" class="form-control" id="name" required [(ngModel)]="name" name="name">
解析:[(ngModel)]繫結元件屬性name。 改用屬性繫結和事件繫結
1 <input type="text" class="form-control" id="name" required           
2     [ngModel]="name" name="name"
3     (ngModelChange)="name = $event" >
解析: [(ngModel)]為屬性繫結,繫結元件屬性name。 (ngModelChange)為事件繫結,看起來可能有點怪。現在來解釋下。 因為ngModelChange並非<input>元素的事件。它實際來自NgModel指令的事件屬性。當Angular在表單中看到[(x)]的繫結目標時,它會期待這個x指令有一個名為x的輸入屬性,和一個名為xChange的輸出屬性。 把這裡的x替換成ngModel,就可以理解得通了。 還有一個一開始看得有點蒙圈的地方,是模板表示式中的model.name = $event。我們理解的$event物件一幫來自DOM事件。但ngModelChange屬性不會生成DOM事件,因為它是Angular EventEmitter型別的屬性。當它觸發時,$event返回的是輸入框的值,也正是希望賦給元件name屬性的值。 總結:在實踐中,我們優先使用[(ngModel)]形式的雙向繫結,只有當時間處理函式需要處理合並或限制按鍵頻率等特殊情況時,才會將雙向資料拆分開來,改成獨立的事件處理函式(即改成上面的程式碼二方式來實現)。 注意: 當在表單中使用[(ngModel)]時,必須要定義name屬性。