# Angular 2 ngModel 雙向綁定
### 數據雙向綁定概括
```html
<input [value]="username" (input)="username = $event.target.value">
<p>Hello {{username}}!</p>
```
說明:
- `[value]="username"` - 綁定表達式`username`到輸入元素的`value`屬性上。
- `(input)="expression"` - 以聲明方式將輸入元素的`input`事件綁定表達式上。
- `username = $event.target.value` - `input`事件觸發后執行的表達式。
- `$event` - Angular暴露在元素中的事件綁定表達式,它代表了事件`event`對象。
注意:這種方式,如果沒有指定`username`的初始值,將在輸入框中顯示`undefined`。傳入`(input)`的`$event`類型為`InputEventObject`
### 理解ngModel
`ngModel`實際上由**屬性綁定**和**事件綁定**兩部分構成。它的完整寫法如下:
```html
<input [ngModel]="username" (ngModelChange)="username = $event">
<p>Hello {{username}}!</p>
```
屬性綁定`[ngModel]`只關心如何更新當前DOM元素,事件綁定`(ngModelChange)`通知外部世界DOM值發生改變。為什么這里的`ngModelChange`接收的是`$event`,而不是像上面`$event.target.value`,原因在于Angular內部的`DefaultValueAccessor`做了一些處理。
最后,`username`和`ngModel`寫二次,顯得沒有必要,Angular允許我們直接使用簡寫方式`[()]`。
### 創建自定義雙向綁定
```html
<custom-counter [(counter)]="someValue"></custom-counter>
<p>counterValue = {{someValue}}</p>
```
```typescript
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'custom-counter',
template: `
<button (click)="decrement()">-</button>
<span>{{counter}}</span>
<button (click)="increment()">+</button>
`
})
export class CustomCounterComponent {
counterValue = 0;
@Output() counterChange = new EventEmitter();
@Input()
get counter() {
return this.counterValue;
}
set counter(val) {
this.counterValue = val;
this.counterChange.emit(this.counterValue);
}
decrement() {
this.counter--;
}
increment() {
this.counter++;
}
}
```
- 說明
- angular 1.x
- ngModelController
- ngOptions
- ngModelOptions
- lifecycle
- directive
- angular 2
- @angular/forms
- 類
- AbstractControl
- AbstractControlDirective
- AbstractFormGroupDirective
- FormControl
- FormArray
- FormBuilder
- FormGroup
- NgControl
- 接口
- controlValueAccessor
- 指令
- DefaultValueAccessor
- Angular 2 生命周期
- OnInit
- DoCheck
- @angular/router
- 配置
- Routes
- 指令
- RouterOutlet
- RouterLink
- 接口
- ActivatedRoute
- UrlTree
- NavigationExtras
- ActivatedRouteSnapshot
- RouterStateSnapshot
- 類
- UrlSegment
- UrlSegmentGroup
- UrlSerializer
- DefaultUrlSerializer
- Router
- bug記得
- @angular/http
- 類
- Http
- Body
- Response
- ResponseOptions
- Header
- Request
- RequestOptions
- URLSearchParams
- @angular/core
- decorator
- Component-decorator
- animation
- DI
- linker
- TemplateRef
- ElementRef
- EmbeddedViewRef
- ViewRef
- ViewContainerRef
- Query
- ComponentFactory
- ComponentRef
- Renderer
- change_detection
- KeyValueDiffers
- IterableDiffers
- ChangeDetectorRef
- ChangeDetectionStrategy
- Zone
- ngZone
- @angular/common
- 指令
- NgTemplateOutlet
- QueryList
- bootstrap4
- card
- form
- 重點關注博客
- 學習過的文章
- 筆記
- Angular 2 雙向綁定
- 將字符串解析成DOM
- rx相關
- operators
- combineLatest
- combineAll
- concat(All, Map, *MapTo)
- 背壓(backpressure)
- js事件keycode對應表
- 裝飾器
- 有用的代碼摘錄
- 日期操作
- 數量操作
- 字符操作
- rxjs問題
- 小示例
- h5面試準備
- react
- 開發遇到的問題