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

[Angular] 笔记 8:list/detail 页面以及@Input

1. list 页面

list/detail 是重要的 UI 设计模式。

vscode terminal 运行如下命令生成 detail 组件:

PS D:\Angular\my-app> ng generate component pokemon-base/pokemon-detail --module=pokemon-base/pokemon-base.module.ts
CREATE src/app/pokemon-base/pokemon-detail/pokemon-detail.component.html (29 bytes)
CREATE src/app/pokemon-base/pokemon-detail/pokemon-detail.component.spec.ts (649 bytes)
CREATE src/app/pokemon-base/pokemon-detail/pokemon-detail.component.ts (306 bytes)
CREATE src/app/pokemon-base/pokemon-detail/pokemon-detail.component.css (0 bytes)
UPDATE src/app/pokemon-base/pokemon-base.module.ts (428 bytes)

也可以使用通过安装 Angular Files 扩展生成上面的 detail 组件:

在这里插入图片描述

安装扩展后可以直接使用右键菜单命令生成组件:

在这里插入图片描述

工程文件结构:

在这里插入图片描述

然后修改 pokemon-base.module.ts:

@NgModule({declarations: [PokemonListComponent, PokemonDetailComponent],imports: [CommonModule],// 增加 PokemonDetailComponentexports: [PokemonListComponent, PokemonDetailComponent],
})
export class PokemonBaseModule {}

工程中现在有两个新生成的组件,pokemon-listpokemon-detail,其中,pokemon-list 是 smart 组件,pokemon-detail 是 dumm 组件。
smart 组件总是向下传递数据给 dumm 组件,smart 组件之所以称为 smart ,是因为它能从数据库获得数据,相对而言,dumm 组件不会访问数据库,它只能从 smart 组件那里接收数据。

接下来将 app.component.ts 中的数据移至更合适的地方,通常来说,app.component.ts 中直接存放数据不是最佳的设计方式。虽然在某些情况下可能需要在 app 组件中保留关键数据,但一般来说, app 中的其他代码能移则移,移到其他更合适的组件中,以提高代码的可维护性和可扩展性。

app.component.ts:

export class AppComponent {constructor() {}// 删除!!!// pokemons: Pokemon[] = [//   // Pokemon: 精灵宝可梦//   {//     id: 1,//     name: 'pikachu', // 皮卡丘//     type: 'electric',//     isCool: false,//     isStylish: true,//   },//   {//     id: 2,//     name: 'squirtle', // 杰尼龟//     type: 'water',//     isCool: true,//     isStylish: true,//   },//   {//     id: 3,//     name: 'charmander', // 小火龙//     type: 'fire',//     isCool: true,//     isStylish: false,//   },// ];
}

将数据粘贴到 pokemon-list.component.ts,模拟从数据库中获取的数据:

import { Component, OnInit } from '@angular/core';
@Component({selector: 'app-pokemon-list',templateUrl: './pokemon-list.component.html',styleUrls: ['./pokemon-list.component.css'],
})
export class PokemonListComponent implements OnInit {// 从 app.component.ts 里剪切过来的数据pokemons: Pokemon[] = [// pokemon: 精灵宝可梦{id: 1,name: 'pikachu', // 皮卡丘type: 'electric',isCool: false,isStylish: true,},{id: 2,name: 'squirtle', // 杰尼龟type: 'water',isCool: true,isStylish: true,},{id: 3,name: 'charmander', // 小火龙type: 'fire',isCool: true,isStylish: false,},];constructor() {}ngOnInit(): void {}
}

app文件夹下新建文件夹models 以及新文件 pokemon.ts, 将用于类型检查的 Pokemon interface 移到此文件中,以后项目中的其他类也可以使用此 interface,这样能够避免代码重复。

在这里插入图片描述

pokemon.ts,

export interface Pokemon {id: number;name: string;type: string;isCool: boolean;isStylish: boolean;
}

相应地,pokemon-list.component.ts 中增加 import { Pokemon } from 'src/app/models/pokemon'; 以使用此 interface.

pokemon-list.component.html:

<table><thead><th>Name</th><th>Index</th></thead><tbody><tr *ngFor="let pokemon of pokemons; let i = index"><td class="pokemon-td" [class.cool-bool]="pokemon.isCool">{{ i }} {{ pokemon.name }}</td></tr><tr *ngFor="let pokemon of pokemons; let i = index"><td class="pokemon-td" [ngClass]="{ 'cool-bool': pokemon.isCool }">{{ i }} {{ pokemon.name }}</td></tr><tr *ngFor="let pokemon of pokemons; let i = index"><tdclass="pokemon-td"[style.backgroundColor]="pokemon.isStylish ? '#800080' : ''">{{ i }} {{ pokemon.name }}</td></tr><tr *ngFor="let pokemon of pokemons; let i = index"><tdclass="pokemon-td"[ngStyle]="{ 'backgroundColor': (pokemon.isStylish ? '#800080' : '') }">{{ i }} {{ pokemon.name }}</td></tr></tbody></table>

运行 ng serve, 可看到如下界面:

在这里插入图片描述

2. detail 页面:

这一步要做的是迭代 pokemons 数组,将每一个 pokemon 传给 detail

在这里插入图片描述
修改 pokemon-detail.component.ts:

import { Component, Input, OnInit } from '@angular/core';
import { Pokemon } from 'src/app/models/pokemon';@Component({selector: 'app-pokemon-detail',templateUrl: './pokemon-detail.component.html',styleUrls: ['./pokemon-detail.component.css'],
})
export class PokemonDetailComponent implements OnInit {// 增加以下两行代码:@Input()detail!: Pokemon; // add a ! - a bang or null operator or null coalescingconstructor() {}ngOnInit(): void {}
}

重构 pokemon-list.component.html:

<table><thead><th>Name</th><th>Index</th></thead><tbody><app-pokemon-detail*ngFor="let pokemon of pokemons"[detail]="pokemon"></app-pokemon-detail></tbody>
</table>

pokemon-detail.component.html:

<tr><td class="pokemon-td" [class.cool-bool]="detail.isCool">{{ detail.id }} : {{ detail.name }}{{ detail.isCool == true ? "is COOL" : "is NOT COOL" }}</td>
</tr>

运行 ng serve:
在这里插入图片描述

3. Input 装饰器

3.1 Angular doc

Input 装饰器用来标记一个类字段为输入属性,并提供配置元数据。input 属性与模板中的一个DOM属性绑定。在变更检测期间,Angular会自动用DOM属性的值更新数据属性。

(Decorator that marks a class field as an input property and supplies configuration metadata. The input property is bound to a DOM property in the template. During change detection, Angular automatically updates the data property with the DOM property’s value.)

3.2 stack overflow

pokemon-detail 是一个子组件,它被设计用于插入到一个拥有 detail 数据的父组件中。此 detail 数据通过被 @Input 装饰器标记为 input 的 detail实例变量传递到 pokemon-detail 组件中。

用法:使用 input 装饰器标记实例变量,使父组件可以通过此变量传数据下来。

@Input()detail: Pokemon; 

父组件接下来将会使用子组件,并传数据给它。

<pokemon-detail [detail]="pokemon"></pokemon-detail>

父组件名为 pokemon 的实例变量含有数据,这些数据将传递到 pokemon-detail 组件中。


Angular For Beginners

相关文章:

  • 嵌入式开发网络配置——windows连热点,开发板和电脑网线直连
  • 从a类到b类理解原型链
  • Python开发GUI常用库PyQt6和PySide6介绍之三:交互和通信方式讲解
  • 第八章 创建Callout Library - ZFentry 链接选项
  • Spring DefaultListableBeanFactory源码分析
  • mvtec3d
  • [架构之路-265]:目标系统 - 设计方法 - 软件工程 - 软件设计 - 如何做好详细设计
  • D9741 PWM控制器电路,定时闩锁、短路保护电路,输出基准电压(2.5V) 采用SOP16封装
  • 【UE5.1】程序化生成Nanite植被
  • 实战10 角色管理
  • redis 从0到1完整学习 (八):QuickList 数据结构
  • Android画布Canvas drawPath绘制跟随手指移动的圆,Kotlin
  • Springcloud Alibaba 使用Canal将MySql数据实时同步到Elasticsearch
  • Git三种方法从远程仓库拉取指定分支
  • Leetcode 2971. Find Polygon With the Largest Perimeter
  • [ JavaScript ] 数据结构与算法 —— 链表
  • 4个实用的微服务测试策略
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • conda常用的命令
  • Go 语言编译器的 //go: 详解
  • Java多态
  • Java精华积累:初学者都应该搞懂的问题
  • JS+CSS实现数字滚动
  • Laravel 菜鸟晋级之路
  • Making An Indicator With Pure CSS
  • Netty+SpringBoot+FastDFS+Html5实现聊天App(六)
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • socket.io+express实现聊天室的思考(三)
  • Swoft 源码剖析 - 代码自动更新机制
  • 分享几个不错的工具
  • 关于Flux,Vuex,Redux的思考
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 开源SQL-on-Hadoop系统一览
  • 力扣(LeetCode)22
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 我是如何设计 Upload 上传组件的
  • 正则与JS中的正则
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • #Spring-boot高级
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (HAL库版)freeRTOS移植STMF103
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (搬运以学习)flask 上下文的实现
  • (附源码)计算机毕业设计SSM基于健身房管理系统
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .net core 源码_ASP.NET Core之Identity源码学习
  • .NET 解决重复提交问题
  • .NET版Word处理控件Aspose.words功能演示:在ASP.NET MVC中创建MS Word编辑器
  • .net操作Excel出错解决
  • .NET框架设计—常被忽视的C#设计技巧
  • .net中应用SQL缓存(实例使用)
  • @entity 不限字节长度的类型_一文读懂Redis常见对象类型的底层数据结构