企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 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++; } } ```