[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 层绑定该事件

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

效果:

在这里插入图片描述

传递 event 对象

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

<label for="server-name">Server Name: {{ serverName }}</label>
<input
  type="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({
  // 新增 FormsModule
  imports: [BrowserModule, FormsModule],
})
export class AppModule {}

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

  1. 修改 V 层代码

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

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

在这里插入图片描述

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

在这里插入图片描述

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

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

    <input
      type="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 层的变化,同时更新数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/372822.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《MySQL》超详细笔记

目录 基本知识 主流数据库 数据库基本概念 MySQL启动 数据库基本命令 数据库 启动数据库 显示数据库 创建数据库 删除数据库 使用数据库 查询当前数据库信息 显示数据库中的表 导入数据库脚本 表 查看表的结构 查看创建某个表的SQL语句 数据库的查询命令 查询…

设计模式学习笔记(一):基本概念;UML

文章目录 参考面向对象的设计原则创建型模式结构型模式行为型模式 UML视图图&#xff08;Diagram&#xff09;模型元素(Model Element)通用机制类之间的关系关联关系复杂&#xff01;&#xff01;聚合关系组合关系 依赖关系泛化关系接口与实现关系 参考 https://github.com/fa…

OpenCV/C++:点线面相关计算(二)

接续&#xff0c;继续更新 OpenCV/C:点线面相关计算_线面相交的点 代码计算-CSDN博客文章浏览阅读1.6k次&#xff0c;点赞2次&#xff0c;收藏12次。OpenCV处理点线面的常用操作_线面相交的点 代码计算https://blog.csdn.net/cd_yourheart/article/details/125626239 目录 1、…

Micro micro controller一览

https://www.microchip.com.cn/&#xff0c; Microchip中文网站 https://www.microchip.com.cn/newcommunity/index.php?mSearch&adosearch&moduleDownload&keyworddsPIC33&p3 Microcontrollers and microProcessors dsPIC33 Digital Signal Controllers (D…

假期刷题打卡--Day24

1、MT1198阶乘差 求1!-2!-3!-…-n! 格式 输入格式&#xff1a; 输入为整型 输出格式&#xff1a; 输出为整型 样例 1 输入&#xff1a; 5输出&#xff1a; -151 分析过程 看到这个题目的时候&#xff0c;感觉这个题目出现的没有必要&#xff0c;就和前面阶乘和一样的…

MySQL数据库练习【一】

MySQL数据库练习【一】 一、建库建表-数据准备二、习题2.1. 查询部门编号为30的部门的员工详细信息2.2.查询从事clerk工作的员工的编号、姓名以及其部门号2.3.查询奖金多于基本工资的员工的信息、查询奖金小于基本工资的员工的信息2.4.查询奖金多于基本工资60%的员工的信息2.5.…

transformers重要组件(模型与分词器)

1、模型&#xff1a; from transformers import AutoModelcheckpoint "distilbert-base-uncased-finetuned-sst-2-english" model AutoModel.from_pretrained(checkpoint) 除了像之前使用 AutoModel 根据 checkpoint 自动加载模型以外&#xff0c;我们也可以直接…

算法学习——LeetCode力扣哈希表篇2

算法学习——LeetCode力扣哈希表篇2 454. 四数相加 II 454. 四数相加 II - 力扣&#xff08;LeetCode&#xff09; 描述 给你四个整数数组 nums1、nums2、nums3 和 nums4 &#xff0c;数组长度都是 n &#xff0c;请你计算有多少个元组 (i, j, k, l) 能满足&#xff1a; 0 …

细说开源软件的影响力分析

开源软件的影响力分析 一、开源软件如何推动技术创新 开源软件以其开放源代码的特性&#xff0c;极大地推动了全球软件技术的创新和发展。这种开放性不仅使得开发者能够自由地查看、修改和使用源代码&#xff0c;还促进了全球开发者之间的深度协作和交流。 1.1 促进全球协作&…

【数据分享】1929-2023年全球站点的逐月平均能见度(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 之前我们分享过1929-2023年全球气象站点的逐月平均气温数据、逐月最高气温数据…

二叉树(4)——二叉树链式结构的实现和递归思想(2)

有了昨天的铺垫&#xff0c;今天就很简单了。先把昨天二叉树的代码复制一下&#xff0c;今天还要用。 代码&#xff1a; typedef int datatype; typedef struct BinaryTree {datatype _data;struct BinaryTree* _left;struct BinaryTree* _right; }BT;BT* CreatNode(datatype…

分享63个节日PPT,总有一款适合您

分享63个节日PPT&#xff0c;总有一款适合您 63个节日PPT下载链接&#xff1a;https://pan.baidu.com/s/1kZeiN06KbevtSCs5vXm6oA?pwd6666 提取码&#xff1a;6666 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理更不易…

宝塔+php+ssh+vscode+虚拟机 远程调试

远程(虚拟机)宝塔 安装扩展 配置文件添加&#xff0c;zend_extension看你虚拟机的具体位置 [Xdebug] zend_extension/www/server/php/74/lib/php/extensions/no-debug-non-zts-20190902/xdebug.so xdebug.modedebug xdebug.start_with_requesttrigger xdebug.client_host&quo…

windows+vscode配置远程Linux开发环境

1.Linux运行sshd服务 安装openssh-server sudo apt install openssh-server 开启服务 sudo service ssh start 检查sshd是否开启 sudo ps -aux | grep sshd 2.vscode上安装RemoteDevelopment插件 其他依赖性会自动安装 3.配置远程Linux主机信息 Linux主机ip 4.在vscode…

用 Delphi 程序调用 Python 代码画曲线图

用 Python 的库画图 Python 代码如下&#xff1a; import matplotlib.pyplot as pltsquares [1, 4, 9, 16, 25]; plt.plot(squares); plt.grid(True) # 网格线 plt.show(); # 这句话会弹出个窗口出来&#xff0c;里面是上述数据的曲线。 把以上代码&#xff0c;放进 PyS…

5分钟掌握接口自动化测试,4个知识点简单易学!

一. 什么是接口测试 接口测试是一种软件测试方法&#xff0c;用于验证不同软件组件之间的通信接口是否按预期工作。在接口测试中&#xff0c;测试人员会发送请求并检查接收到的响应&#xff0c;以确保接口在不同场景下都能正常工作。 就工具而言&#xff0c;常见的测试工具有…

DBNet详解及训练ICDAR2015数据集

论文地址&#xff1a;https://arxiv.org/pdf/1911.08947.pdf 开源代码pytorch版本&#xff1a;GitHub - WenmuZhou/DBNet.pytorch: A pytorch re-implementation of Real-time Scene Text Detection with Differentiable Binarization 前言 在这篇论文之前&#xff0c;文字检…

07.你还在手动部署代码吗

如今的项目或者个人项目中,大家的代码怎么部署呢?公司一般都有完整的持续集成以及持续交付平台,对于小公司可能也有各自搭建了一些,比如jenkins,以及gitlab集成的gitlab-ci等等,这些都可以完成我们部署的工作甚至是测试集成等等一系列流水化工作。 但是,即使如此,我依…

R语言学习case12:ggplot 置信区间(多线型)

接上文&#xff1a;多条曲线 R语言学习case11&#xff1a;ggplot 置信区间&#xff08;包含多子图&#xff09; 在ggplot2中&#xff0c;每个geom函数都接受一个映射参数。然而&#xff0c;并非每个美学属性都适用于每个geom。你可以设置点的形状&#xff0c;但不能设置线的“…

从雪花到分形几何

目录 前言雪花曲线分形几何雪花曲线工程化参考文献前言 新一股寒潮来袭,河南,安徽,重庆,湖北,湖南北部等地都飘起了大雪,一夜的功夫,世界银装素裹,雪白雪白的,好不美丽迷人。 雪花曲线 物理学上,雪花是一种晶体,是天空中的水汽经凝华而来的固态降水,结构随温度…