当前位置: 首页 > news >正文

[Angular 基础] - 数据绑定(databinding)

[Angular 基础] - 数据绑定(databinding)

上篇笔记,关于 Angular 的渲染过程及组件的创建&简单学习:[Angular 基础] - Angular 渲染过程 & 组件的创建

Angular 之中的 databinding 是一个相对而言更加复杂,以及我个人觉得相对而言比较灵活的部分——较之 React 的单项数据流而言,Angular 是可以实现双重绑定的:

在这里插入图片描述

对于 React 来说,则是需要调用从 ViewModel 中传给 View 层的事件,随后 ViewModel 更新数据,再传递到 View 层,总体上来说 React 的代码更加的可靠(因为数据/事件的流动是单一的),但是也会碰到情况——如嵌套较深时,事件的触发与数据的更新就会产生比较麻烦的情况

这也是二者对于事件和数据处理的不同之处

本篇笔记会对 Angular 的数据绑定进行更加深入地学习

数据传输

即 ViewModel 层将数据传输给 View 层,这里主要学习两种方式:字符串插值(string interpolation) 和 属性绑定(property binding)

string interpolation

string interpolation 是一种比较方便的将数据从 ViewModel 传到 View 层的方法,只需要在中组件中声明对应的变量/方法,并且在 HTML Template 中调用即可。用法如下:

  1. 在组件中声明变量/方法

    export class ServerComponent {serverId = 10;serverStatus = 'offline';getServerStatus() {return this.serverStatus;}
    }
    
  2. 使用 {{ var/method() }} 的方式调用

    <p>{{ "Server" }} with ID {{ serverId }} is {{ getServerStatus() }}</p>
    

    ⚠️:var/method() 为一个表达式

效果为:

在这里插入图片描述

缺点在于:

  • 返回值必须是字符串

    如果是 primitive type 那么问题不大,数字、布尔值都是可以直接转成字符串,因此正常渲染

    如果是对象的话,则会调用默认的 toString 方法,对于很多没有重写 toString 方法的对象/类来说,则是不可读的 object

  • 代码无法非常复杂

    如果需要写表达式,那么有一个 一行 的限制

    换句话说三元式可用,if/else 不可用

  • 无法赋值或创建新的变量

    以面用的例子来说 {{ serverId = 20 }} 是会直接报错的:

    在这里插入图片描述

  • 调用的函数不能有副作用(side effect)

    换言之,只能调用 getter,不能调用 setter

  • 安全性问题

    像 React 一样,Angular 也会清理从 ViewModel 传向 View 层的数据

    但是如果同时使用 string interpolation 和 bypassSecurityTrust,那么当前代码就不会被清洗,如果中间有一些比较危险的代码,那么就会引起安全性的问题

    举例说明就是,如果当前应用有一个功能是去渲染用户之前留下的 comment,这里决定使用 string interpolation 去渲染用户的留言,而开发者假设用户的数据一定是干净的(后段已经进行过处理),所以决定使用 bypassSecurityTrust

    后端也是这么觉得的,因此并没有清理用户数据

    用户的数据里包含了攻击代码——如窃取当前网页中的 JWT token,自动在后台运行来自其他域名的攻击脚本等

    那么就会引发这个安全性的问题,这个情况类似于 React 中直接食用 dangerouslySetInnerHTML

property binding

string interpolation 相当于是在页面上渲染一段文字,有的时候则需要更加动态的控制 DOM 元素的属性,比较常见的案例有,在发送了验证短信后一分钟内按钮呈现 disabled 的状态,或是大部分 input 元素中的 value 等,这些都无法使用 string interpolation 来解决,还是需要使用另一个不同的语法,也就是 property binding,用法如下:

  1. 依旧在 ___.component.ts 中声明对应的变量

    export class ServersComponent {allowNewServer = false;constructor() {setInterval(() => {console.log(new Date().toISOString(),'allowNewServer: ',this.allowNewServer);this.allowNewServer = !this.allowNewServer;}, 2000);}
    }
    

    这里的设定是每 2s 将 allowNewServer 的值翻转一下

  2. 在 HTML template 中使用 [attribute]='var/method()' 的方式调用

    <button class="btn btn-primary" [disabled]="!allowNewServer">Add Server
    </button>
    

    这里还没有新增 Add Server 的功能,这里主要是看 disable 的状态

    ⚠️:var/method() 为一个表达式

效果为:

在这里插入图片描述

本质上来说,如果只是渲染一段文字的话,使用 string interpolation 会比较方便,如果是要绑定属性的话,则是使用 property binding,原因是二者没法互用,如下面的例子:

<p>{{ allowNewServer }}</p>
<p [innerText]="allowNewServer"></p>

的效果是一样的,但是混用就会报错:

在这里插入图片描述

事件绑定

数据从 View 层传输到 ViewModel 层,其绑定的方式与 property binding 相似:

  • VM 层实现一个事件

    export class ServersComponent {serverCreationStatus = 'No server was created!';onCreateServer() {this.serverCreationStatus = 'Server was created!';}
    }
    
  • V 层绑定该事件

    <buttonclass="btn btn-primary"[disabled]="!allowNewServer"(click)="onCreateServer()"
    >Add Server
    </button>
    

效果:

在这里插入图片描述

传递 event 对象

这里需要对 event 事件对象进行绑定,View 层修改如下:

<label for="server-name">Server Name: {{ serverName }}</label>
<inputtype="text"class="form-control"id="server-name"(input)="onUpdateServerName($event)"
/>

这时候就可以在 ViewModel 中接收到 $event 了:

  onUpdateServerName($event: Event) {this.serverName = (<HTMLInputElement>$event.target).value;}

此时的效果为:

在这里插入图片描述

其实到此的实现和 React 还是挺像的,V 层调用 VM 层的表达式,将事件对象传到 VM 层;VM 层处理 business logic,将修改过的代码反映到 V 层上。不过下一个双向绑定就能确实的展现 React 和 Angular 在数据传输上的区别了。

⚠️:这里变量名称使用 $event 是一个预定俗称的规则(convention),可以改成其他的名称

❗:注意这里的 value 没有通过 property binding 实现绑定,所以这里的数据显示的是 input 里的数据

双向绑定

‼️:在使用双向绑定前必须要先在 AppModule 中导入 FormsModule,如:

// 导入 FormsModule
import { FormsModule } from '@angular/forms';@NgModule({// 新增 FormsModuleimports: [BrowserModule, FormsModule],
})
export class AppModule {}

接下来就可以使用 ngModel 了,具体使用如下:

  1. 修改 V 层代码

    <inputtype="text"class="form-control"id="server-name"[(ngModel)]="serverName"
    />
    

VM 层则不需要修改,最终效果如下:

在这里插入图片描述

乍一看好像 2 way databinding 和之前的实现没什么区别,不过如果将二者代码同时渲染,并且修改一下 serverName 的默认值,就能看到区别了:

在这里插入图片描述

  1. 使用 [(ngModel)] 同时兼具了 event binding 和 property binding

    对比起来,不使用 2 way binding 想要达成以下效果则需要这样的实现:

    <inputtype="text"class="form-control"id="server-name"(input)="onUpdateServerName($event)"[value]="serverName"
    />
    
  2. 数据的同步方式不一样

    使用 property binding+event binding 的效果看起来和 2 way binding 一样,不过实际上它还是通过把值从 VM 层传到 V 层进行数据渲染,V 层调用 VM 层的 change handler 去实现数据变更,因此本质上它的 flow 还是 VM 层到 V 层的单方向实现

    2 way binding 则会让 VM 层监听 V 层的变化,因此当 V 层的数据变化时,VM 层的数据也会同时进行更新。而如果其他地方也有 change handler 修改了 VM 层中的数据,则 V 层也能监听到 VM 层的变化,同时更新数据

相关文章:

  • nginx复现负载均衡案例
  • spring boot学习第九篇:操作mongo的集合和集合中的数据
  • 爬虫实战--人民网
  • 记一次CPU有规律飙高的线上问题排查过程
  • JAVA面试汇总总结更新中ing
  • 【AI数字人-论文】Geneface论文
  • 【芯片设计- RTL 数字逻辑设计入门 6 -- 带同步复位的D触发器 RTL实现及testbench 验证】
  • JAVA中的main方法
  • 【方法论】费曼学习方法
  • 【Spring Boot 3】【JPA】嵌入式对象
  • 文心一言4.0API接入指南
  • 2024Node.js零基础教程(小白友好型),nodejs新手到高手,(五)NodeJS入门——http模块
  • C# OpenCvSharp DNN 部署yolov4目标检测
  • Linux 性能调优之存储设备调优
  • GADM 4.1 全球国家行政区划下载
  • CAP理论的例子讲解
  • Django 博客开发教程 16 - 统计文章阅读量
  • docker python 配置
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • es的写入过程
  • Facebook AccountKit 接入的坑点
  • LeetCode29.两数相除 JavaScript
  • mongodb--安装和初步使用教程
  • PAT A1120
  • Spring Cloud中负载均衡器概览
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • yii2中session跨域名的问题
  • 当SetTimeout遇到了字符串
  • 工程优化暨babel升级小记
  • 好的网址,关于.net 4.0 ,vs 2010
  • 回顾2016
  • 机器学习中为什么要做归一化normalization
  • 技术:超级实用的电脑小技巧
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 我的zsh配置, 2019最新方案
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • # Java NIO(一)FileChannel
  • # Panda3d 碰撞检测系统介绍
  • #define
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (全注解开发)学习Spring-MVC的第三天
  • (十六)一篇文章学会Java的常用API
  • (一)kafka实战——kafka源码编译启动
  • (一)认识微服务
  • (转)LINQ之路
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • *p=a是把a的值赋给p,p=a是把a的地址赋给p。
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .net framwork4.6操作MySQL报错Character set ‘utf8mb3‘ is not supported 解决方法
  • .NET 常见的偏门问题