[Angular 基础] - 指令(directives)

news2025/1/20 19:10:21

[Angular 基础] - 指令(directives)

这里假设已经知道如何创建 Angular 组件以及数据绑定,不然可以参考前两篇笔记:

  • [Angular 基础] - Angular 渲染过程 & 组件的创建

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

就像中文翻译一样,directives 就是指令,它就是一系列 DOM 中存在的指令

component directive

Component 这个 declaration 就是一个最基础的指令,当运行:

import { Component } from '@angular/core';

@Component({
  selector: 'app-my-component',
  template: `<p>Hello, world!</p>`,
})
export class MyComponent {}

这段代码的时候,其实就已经是在运行一个指令,这个指令做了下面几件事情:

  • @Component 表明下面声明的类是一个组件
  • selector 定义一个元素,该元素会接受当前组件内的 HTML Template
  • template 定义一个 HTML Template,将会展现在 app-my-component 这个 HTML 元素中

这就是当前需要遵从的指令,我个人理解是通知 DOM 需要渲染哪个对应的 HTML Template

以此类推,@NgModule, @Directive 等也是对应的 component directive

structural directives

structural directives 的指令是通知 DOM 增加或删除特定的 HTML 元素。目前主流的内置 structural directives 有 3 个:*ngIf, *ngFor*ngSwitch,当然,这不代表 Angular 之提供了这三个 structural directives

除此之外,开发者自己也可以创建相应的 structural directives

*ngIf

语法为 *ngIf="expression",并且这个表达式(expression) 需要返回一个 boolean。依旧使用之前的案例,这里假设点击 add server 的按钮会实现对应功能,并且需要向用户显示新的组件已经生成

对应的 View 层修改如下:

<!-- 其余显示添加 server 的 input 和 button 这里不重复了 -->
<p *ngIf="serverCreated">Sever was created, server name is {{ serverName }}</p>

对应的 VM 层修改如下:

// 新增加的变量,只有在用户点击创建 server 的 btn 时才需要显示信息
  serverCreated = false;

  onCreateServer() {
    this.serverCreationStatus = 'Server was created!';
    this.serverCreated = true;
  }

效果如下:

在这里插入图片描述

可以看到只有当 *ngif 里的条件为 true 时,该 DOM 才会渲染

有了 if 也会有 else 条件,这时候 V 层的代码可以这么修改:

<p *ngIf="serverCreated; else noServer">
  Sever was created, server name is {{ serverName }}
</p>
<ng-template #noServer>
  <p>No server was created!</p>
</ng-template>

这里使用了一个特殊的 HTML 元素——ng-template,它主要的用途是为了搭配 structural directives 去使用的;这里 #noServer 是对 ng-template 这一元素的引用变量名

*ngIf v17 的更新

目前有一个新的语法可以重置 ngIf,它的语法就是 @for,使用方式如下:

@if (serverCreated) {
<p>Sever was created, server name is {{ serverName }}</p>
} @else {
<p>No server was created!</p>
}

其展示的效果是一样的,else if 的语法则为 @else if

这个语法是 v17 最新推出的版本,暂时还不是 production-ready,所以只在这里提一下,不会深入研究

ngFor

这是一个可以循环渲染 HTML 元素的方式,用法如下:

  • 修改 VM 层

    这里会新增一个 servers 的数组,并且在 onCreateServer 中将新添的 serverName 推到数组中去:

    servers = ['Test Server', 'Test Server2'];
    
    onCreateServer() {
        this.serverCreationStatus = 'Server was created!';
        this.servers.push(this.serverName);
        this.serverCreated = true;
    }
    
  • 修改 V 层

    这里就使用 *ngFor 去渲染整个数组:

    <app-server *ngFor="let server of servers"></app-server>
    

最终效果如下:

在这里插入图片描述

⚠️:这里还没有涉及到组件之间数据的传输,所以 serverName 不会动态渲染

相比较 ngIfngFor 的语法更复杂一些,它的完整语法如下:

<div
  *ngFor="
    let item of servers;
    trackBy: trackByFn;
    index as i;
    first as isFirst;
    last as isLast;
    even as isEven;
    odd as isOdd
  "
>
  {{ i }}: {{ item }}
  <span *ngIf="isFirst">(first)</span>
  <span *ngIf="isLast">(last)</span>
  <span *ngIf="isEven">(even)</span>
  <span *ngIf="isOdd">(odd)</span>
</div>

其中 trackByFn 写在了 VM 层:

  trackByFn(index: number, item: string) {
    return item;
  }

最终展现的效果如下:

在这里插入图片描述

这里的 trackBy: trackByFn; 是 Angular 提出的一个优化方案,当它存在的时候,Angular 会检查当前返回值是否变更,如果不变更的话将不会重新渲染当前的 DOM 结点

至于 first, last 这四个是 Angular 提供的值,以便可以轻松检查这些边界条件

*ngFor v17 的更新

这个语法如下:

@for (item of items: track item.id) {
<li>{{ item.title }}</li>
}

这个语法是 v17 最新推出的版本,暂时还不是 production-ready,所以只在这里提一下,不会深入研究

ngSwitch

它的语法则类似于 switch,修改的代码如下:

<div
  *ngFor="
    let item of servers;
    trackBy: trackByFn;
    index as i;
    first as isFirst;
    last as isLast;
    even as isEven;
    odd as isOdd
  "
>
  {{ i }}: {{ item }}
  <span *ngIf="isFirst">(first)</span>
  <span *ngIf="isLast">(last)</span>
  <span *ngIf="isEven">(even)</span>
  <span *ngIf="isOdd">(odd)</span>
  <div [ngSwitch]="item">
    <p *ngSwitchCase="'red'">You picked red server!</p>
    <p *ngSwitchCase="'blue'">You picked blue server!</p>
    <p *ngSwitchCase="'green'">You picked green server!</p>
    <p *ngSwitchDefault>Pick a server name</p>
  </div>
</div>

效果如下:

在这里插入图片描述

*ngSwitch v17 的更新

这个语法如下:

@switch (expression) { @case value1:
<p>value1</p>
@case value2:
<p>value2</p>
}

这个语法是 v17 最新推出的版本,暂时还不是 production-ready,所以只在这里提一下,不会深入研究

attribute directives

structural directives 控制的是 DOM 元素的增删(是否渲染),那么 attribute directives 控制的则是渲染 DOM 中的属性

这里也会列举主流用的 3 个,同样,这也不代表 Angular 仅仅提供了这 3 个 structural directives,而且开发者同样也可以创建自己的 structural directives

ngModel

这个在之前的笔记里已经提过了,NgModel 主要提供的是双向绑定的功能

ngStyle

ngStyle 就是比较简单的控制 CSS 的地方,用法如下:

<p
  [ngStyle]="{
   'background-color': serverStatus === 'offline' ? 'red' : 'green'
 }"
>
  {{ "Server" }} with ID {{ serverId }} is {{ getServerStatus() }}
</p>

效果如下:

在这里插入图片描述

⚠️:以上代码修改在 server.component.html

❗:如果无法正确渲染,请查看 servers.component.html 中的 ngFor 是不是返回 <app-server></app-server>

⚡:ngStyle 是 attribute directives,[ngStyle] 则是使用了 property binding

🛣️:'backgound-color' 还有另一个写法是用驼峰命名法 backgroundColor,而 : 后面的也只是需要一个表达式,这里用了三元式,也可以单独创建一个方法

ngClass

这个指令则是动态更新类名,这里实现代码如下:

<p
  [ngStyle]="{
    'background-color': serverStatus === 'offline' ? 'red' : 'green'
  }"
  [ngClass]="{
    online: serverStatus === 'online',
    offline: serverStatus === 'offline'
  }"
>
  {{ "Server" }} with ID {{ serverId }} is {{ getServerStatus() }}
</p>

至于 VM 层也需要添加对应的 CSS:

@Component({
  selector: 'app-server',
  templateUrl: './server.component.html',
  styles: [
    `
      .online {
        color: cyan;
      }

      .offline {
        color: lightgray;
      }
    `,
  ],
})
export class ServerComponent {}

最终效果如下:

在这里插入图片描述

总结

下面都是个人理解,对我来说 directives 解决的是下面的问题:

在这里插入图片描述

  • component directive

    • what

      其实也可以用 which 代替,目前接触过的有两个 directives:

      • @Component 来说是哪个 HTML Template

      • @NgModule 是哪个对应的 NgModule

    • where

      这个目前接触到的是 @Component 中的 selector,这里决定哪里会渲染对应的指代组件

  • structural directive

    这个可以解决一个 when 的问题,即什么情况下会渲染对应的组件

    if/elseswitchfor 循环,都是在满足一定条件下才会渲染对应的组件

  • attribute directive

    这个则是解决了一个 how 的问题,即如何渲染对应组件

    ngModel 的双向绑定,ngClass 的添加对应类,ngStyle 的对应样式,都可以满足一个 how 的问题

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue-Vue3 集成编辑器功能

1、安装依赖 编辑器插件需要安装 wangeditor/editor 和 wangeditor/editor-for-vue 两个插件 npm install wangeditor/editor --savevue3运行如下命令安装 npm install wangeditor/editor-for-vuenext --savevue2运行如下命令安装 npm install wangeditor/editor-for-vue -…

清平乐-春风丽日

今天&#xff0c;是2024年农历除夕日&#xff0c;远方家人已于昨夜风尘扑扑地倦鸟归巢&#xff0c;团聚过龙年&#xff0c;今晨酣睡未起。老龄笔者心情极佳&#xff0c;一夜好梦醒来&#xff0c;推窗仰头展望苍穹&#xff0c;喜上心头&#xff1a;啊&#xff01;接连几天的小雨…

containerd中文翻译系列(十八)containerd支持NRI

节点资源接口 NRI 是节点资源接口&#xff08;Node Resource Interface&#xff09;&#xff0c;它是一个通用框架&#xff0c;用于将扩展功能插入兼容 OCI 的容器运行时。它提供了插件跟踪容器状态并对其配置进行有限的更改改的基本机制。 NRI 本身与任何容器运行时的内部实…

MySQL篇----第十五篇

系列文章目录 文章目录 系列文章目录前言一、实践中如何优化 MySQL二、优化数据库的方法三、简单描述 MySQL 中,索引,主键,唯一索引,联合索引的区别,对数据库的性能有什么影响(从读写两方面)前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分…

Cilium CNI深度指南

Cilium是基于eBPF的功能强大的CNI插件&#xff0c;为云原生环境提供了强大的网络和安全支持。原文: Cilium CNI: A Comprehensive Deep Dive Guide for Networking and Security Enthusiasts! &#x1f313;简介 欢迎阅读为网络和安全爱好者提供的全面深入的指南&#xff01; 本…

Django(十)

1. Ajax请求 浏览器向网站发送请求时&#xff1a;URL 和 表单的形式提交。 GETPOST 特点&#xff1a;页面刷新。 除此之外&#xff0c;也可以基于Ajax向后台发送请求&#xff08;偷偷的发送请求&#xff09;。 依赖jQuery编写ajax代码 $.ajax({url:"发送的地址"…

《剑指 Offer》专项突破版 - 面试题 37 : 小行星碰撞(C++ 实现)

题目链接&#xff1a;LCR 037. 行星碰撞 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 输入一个表示小行星的数组&#xff0c;数组中每个数字的绝对值表示小行星的大小&#xff0c;数字的正负号表示小行星运动的方向&#xff0c;正号表示向右飞行&#xff0c;负…

探索设计模式的魅力:代理模式揭秘-软件世界的“幕后黑手”

设计模式专栏&#xff1a;http://t.csdnimg.cn/U54zu 目录 引言 一、魔法世界 1.1 定义与核心思想 1.2 静态代理 1.3 动态代理 1.4 虚拟代理 1.5 代理模式结构图 1.6 实例展示如何工作&#xff08;场景案例&#xff09; 不使用模式实现 有何问题 使用模式重构示例 二、…

HttpClient | 支持 HTTP 协议的客户端编程工具包

目录 1、简介 2、应用场景 3、导入 4、API 5、示例 5.1、GET请求 5.2、POST请求 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应用开发、数据结构和算法&#xff0c;初…

Spring Boot 笔记 004 自动配置和自定义starter

003讲到了导入jar包中的方法&#xff0c;但其实是个半成品&#xff0c;别人写的jar包中的方法我要在自己的代码中去调用&#xff0c;非常的不方便。原则上写给别人用的jar包&#xff0c;人家要能直接用&#xff0c;而不用写注入的方法。 在springboot中会自动扫描imports文件中…

ThinkPad X201 经典小黑 折腾玩

前段时间&#xff0c;在折腾ThinkPad T430时&#xff0c;偶然看到了ThinkPad X200&#xff0c;一个12.1英寸的高端便携小本。 想当年&#xff0c;但那是总裁级别才能用的&#xff0c;应该是接近2万元&#xff0c;我们是一直用DELL的。 没想到的是&#xff0c;在海鲜市场上&am…

[office] excel如何计算毛重和皮重的时间间隔 excel计算毛重和皮重时间间隔方法 #笔记#学习方法

excel如何计算毛重和皮重的时间间隔 excel计算毛重和皮重时间间隔方法 在日常工作中经常会到用excel&#xff0c;有时需要计算毛重和皮重的时间间隔&#xff0c;具体的计算方式是什么&#xff0c;一起来了解一下吧 在日常工作中经常会到用excel&#xff0c;在整理编辑过磅数据…

贵金属交易包括哪些?香港有哪些贵金属交易平台?

随着金融市场的不断发展&#xff0c;贵金属交易作为一种投资方式&#xff0c;越来越受到投资者的关注。贵金属交易不仅具有投资价值&#xff0c;还能够为投资者提供规避风险和保值的工具。本文将介绍贵金属交易的种类和香港的贵金属交易平台。 一、贵金属交易的种类 贵金属交…

【开源】JAVA+Vue.js实现高校实验室管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实验管理模块2.4 实验设备模块2.5 实验订单模块 三、系统设计3.1 用例设计3.2 数据库设计 四、系统展示五、样例代码5.1 查询实验室设备5.2 实验放号5.3 实验预定 六、免责说明 一、摘…

个人IP塑造与短视频带货,人人都是吸金的网红博主

一、教程描述 网红带货&#xff0c;就是网络红人通过推荐和分享&#xff0c;间接销售产品的一种方式。网红带货并不是直接带货&#xff0c;而是需要打造自己&#xff0c;用时下热门的话讲叫塑造IP&#xff0c;一般通过旅行、工作、日常服装搭配等这些行为&#xff0c;输出自己…

2024-02-08 Unity 编辑器开发之编辑器拓展1 —— 自定义菜单栏与窗口

文章目录 1 特殊文件夹 Editor2 在 Unity 菜单栏中添加自定义页签3 在 Hierarchy 窗口中添加自定义页签4 在 Project 窗口中添加自定义页签5 在菜单栏的 Component 菜单添加脚本6 在 Inspector 为脚本右键添加菜单7 加入快捷键8 小结 1 特殊文件夹 Editor ​ Editor 文件夹是 …

数据在内存中的存储:深入了解与理解技巧

​ ✨✨ 欢迎大家来到贝蒂大讲堂✨✨ ​ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; ​ 所属专栏&#xff1a;C语言学习 ​ 贝蒂的主页&#xff1a;Betty‘s blog 引言 ​ 我们早就学完基本的数据类型&#xff0c;那这些数据类型…

PCIe学习笔记(1)Hot-Plug机制

文章目录 Hot-Plug InitHot Add FlowSurprise Remove FlowNPEM Flow Hot-Plug Init PCIe hot-plug是一种支持在不关机情况下从支持的插槽添加或删除设备的功能&#xff0c;PCIe架构定义了一些寄存器以支持原生热插拔。相关寄存器主要分布在Device Capabilities, Slot Capabili…

【Linux系统学习】2.Linux基础命令

Linux基础命令 Linux的目录结构 Linux命令入门 目录切换相关命令(cd/pwd) 相对路径、绝对路径和特殊路径符 创建目录命令(mkdir) 文件操作命令part1(touch、cat、more&#xff09; 文件操作命令part2(cp、mv、rm&#xff09; 查找命令(which、find&#xff09; grep、wc和管道符…

零基础学编程怎么入手,中文编程工具构件箱之渐变背景构件用法教程,系统化的编程视频教程上线

零基础学编程怎么入手&#xff0c;中文编程工具构件箱之渐变背景构件用法教程&#xff0c;系统化的编程视频教程上线 一、前言 今天给大家分享的中文编程开发语言工具资料如下&#xff1a; 编程入门视频教程链接 https://edu.csdn.net/course/detail/39036 编程工具及实例…