多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] >[success] # 双向绑定 >[success] ## input事件 + value 组合 ![](https://img.kancloud.cn/cf/06/cf06195bd1f2aade02bcb1aeb3e046c0_1300x656.png) 这个 **双向绑定** 有点类似 **vue** 的 **@input + value** 的组合。 这里有个问题,在 **html** 中直接使用 **$event.target.value** 会报错,因为 **ts 不知道这个东西是否存在** ,所以就需要使用 **$any() ,这个html中的方法就相当于 ts里面的 as any的操作.** ,具体说明我在网上查了一些[文档](https://blog.csdn.net/Damien_J_Scott/article/details/117460992),**$any()** 也有可能会有问题,直接定义一个方法把,然后在方法内写赋值逻辑 **html代码** ~~~ <input type="text" [value]="username" (input)="username = $any($event.target).value" /> <span>你好,{{ username }}</span> ~~~ **ts代码** ~~~ import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-horizontal-grid', templateUrl: './horizontal-grid.component.html', styleUrls: ['./horizontal-grid.component.css'] }) export class HorizontalGridComponent implements OnInit { username = ''; constructor() {} ngOnInit() {} } ~~~ >[success] ## ngModel ![](https://img.kancloud.cn/a3/49/a3490e1499618a97de449b972cb92d5d_1229x615.png) **ngModel** 跟 **vue** 的 **v-model** ,很像,在使用 **ngModel**,之前,我们需要在 **app.module.ts** 中引入 **FormsModule** 才可以使用 ![](https://img.kancloud.cn/56/b9/56b98ce06254fc6706d716eff18f3562_1135x837.png) **html代码** ~~~ <input type="text" [(ngModel)]="username" /> <span>你好,{{ username }}</span> ~~~ **ts代码** ~~~ import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-horizontal-grid', templateUrl: './horizontal-grid.component.html', styleUrls: ['./horizontal-grid.component.css'] }) export class HorizontalGridComponent implements OnInit { username = ''; constructor() {} ngOnInit() {} } ~~~ >[success] ## 实现一个双向数据绑定(根据vue写法推断出来的) 1. **父组件写法:** **父组件 html** ~~~ <app-horizontal-grid [(username)]="username"></app-horizontal-grid> ~~~ **父组件 ts** ~~~ { username = '默认值'; } ~~~ 2. **子组件写法:** **子组件 html** ~~~ <input type="text" [value]="username" (input)="handleInput($event)" /> ~~~ **子组件 ts** ~~~ import { Component, EventEmitter, Input, Output } from '@angular/core'; @Component({ selector: 'app-horizontal-grid', templateUrl: './horizontal-grid.component.html', styleUrls: ['./horizontal-grid.component.css'] }) export class HorizontalGridComponent { // 父组件传入的 username 属性 @Input() username = ''; // 定义 emit 方法 @Output() usernameChange = new EventEmitter(); // eslint-disable-next-line @typescript-eslint/no-empty-function constructor() {} // input监听事件 handleInput(ev: any) { // 通过 emit 把 input 更新的值,传给父组件 this.usernameChange.emit(ev.target.value); } } ~~~ >[success] ## 实现一个双向数据绑定(angular视频版本) 实际上 **vue 版本与 angula r版本实现的效果是一样的** ,本质上都是相同的,**都是在数据变化时,通过 **emit** 把数据传递给父组件**,**vue 版本是通过 **Oninput** 事件变化时传递给父组件,而 angular 版本是通过计算属性 get set ,每次 set 时监听数据变化,就通过 emit 把数据回传给父组件** 1. **父组件写法:** **父组件 html** ~~~ <app-horizontal-grid [(username)]="username"></app-horizontal-grid> ~~~ **父组件 ts** ~~~ { username = '默认值'; } ~~~ 2. **子组件写法(不同之处就是在子组件的 get set这里)**: **子组件 html** ~~~ <input type="text" [value]="username" (input)="username = $any($event.target).value" /> ~~~ **子组件 ts** ~~~ import { Component, EventEmitter, Input, Output } from '@angular/core'; @Component({ selector: 'app-horizontal-grid', templateUrl: './horizontal-grid.component.html', styleUrls: ['./horizontal-grid.component.css'] }) export class HorizontalGridComponent { private _username = ''; // 私有属性 // 定义 emit 方法 @Output() usernameChange = new EventEmitter(); // eslint-disable-next-line @typescript-eslint/no-empty-function constructor() {} // 获取 username @Input() public get username(): string { return this._username; } // 写入 username public set username(value: string) { this._username = value; // 通过 emit 把 input 更新的值,传给父组件 this.usernameChange.emit(value); } } ~~~