Angular基础知识学习(一)上

简介: Angular基础知识学习(一)上

属性、元素操作以及指令


普通数据


新建 news 组件,首先在 news.component.ts 文件中定义变量:


import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-news',
  templateUrl: './news.component.html',
  styleUrls: ['./news.component.css']
})
export class NewsComponent implements OnInit {
  title = 'Hello hresh';
  public name: any = 'hresh';
  content: any = '<h3>Hello Java</h3>';
  msg = '中国,你好';
  constructor() {
    this.msg = '你好中国';
  }
  ngOnInit(): void {
  }
}
复制代码


在 html 文件中定义标签来获取定义的变量并显示:


<div>
  <p>news works!</p>
    <!--数据文本绑定-->
  <h3>{{title}}</h3>
  <hr />
  <h1>{{content}}</h1>
  <br>
    <!--绑定 html-->
  <span [innerHTML]="content"></span>
  <br>
  <h2>{{msg}}</h2>
  <br>
  1+1={{1+1}}
</div>
复制代码


效果图如下:


image.png


图片展示


图片资源可以是本地资源,也可以从网上获取,在 html 文件中做如下配置:


<h3>引入图片</h3>
  <img src="assets/images/10001.png" alt="hello" />
  <hr>
  <img [src]="picUrl" />
  <img src="{{picUrl}}" />
复制代码


本地静态资源存放位置如下:


1.jpg


网上图片资源链接可以在 argular01.component.ts 中定义:


public picUrl = 'https://cn.bing.com/th?id=OIP.bbd7bi181qua_NdZzguE3QHaE6&pid=Api&rs=1';
复制代码


网页展示图如下:


2.jpg


模板引用变量


模板引用变量 通常是对模板中 DOM 元素的引用。它还可以引用指令(包含组件)、元素、TemplateRef 或 Web Component 。


使用井号(#)声明模板引用变量。以下模板引用变量 #phone 会在 input 元素上声明了一个 phone 变量。


<input #phone placeholder="phone number" />
<!-- lots of other elements -->
<!-- phone refers to the input element; pass its `value` to an event handler -->
<button (click)="callPhone(phone.value)">Call</button>
复制代码


模板引用变量的范围是整个模板。因此,不要在同一模板中多次定义相同的变量名,因为它在运行时的值将不可预测。


替代语法


你也可以用 ref- 前缀代替 #。 下面的例子中就用把 fax 变量声明成了 ref-fax 而不是 #fax


<input ref-fax placeholder="fax number" />
<button (click)="callFax(fax.value)">Fax</button>
复制代码


NgFor



ngFor 指令迭代父组件的 items 属性所返回的 items 数组,并在每次迭代期间将 item 设置为该数组中的当前条目。 NgFor 指令上下文中的 index 属性在每次迭代中返回该条目的从零开始的索引。 您可以在模板输入变量中捕获 index,并在模板中使用它。


同样在 news 组件中,首先定义数组内容:


nums: any[] = [111, 2222, 333];
public values: Array<string> = ['111', '222', '333'];
userList: any[] = [
    {
        name : 'hresh',
        age : 22
    },
    {
        name : 'hresh2',
        age : 22
    },
    {
        name : 'hresh3',
        age : 22
    }
]
cars: any[] = [
    {
        name: '宝马',
        list: [
            {
                title: 'x1',
                price: '30万'
            },
            {
                title: 'x2',
                price: '30万'
            },
            {
                title: 'x3',
                price: '30万'
            }
        ]
    },
    {
        name: '奔驰',
        list: [
            {
                title: 'x1',
                price: '30万'
            },
            {
                title: 'x2',
                price: '30万'
            },
            {
                title: 'x3',
                price: '30万'
            }
        ]
    }
]
复制代码


在 html 文件中添加内容:


<ul>
    <li *ngFor="let item of nums">
      {{item}}
    </li>
  </ul>
  <br>
  <ul>
    <li *ngFor="let item of userList">
      {{item.name}}---{{item.age}}
    </li>
  </ul>
  <br>
  <ul>
    <li *ngFor="let item of cars">
      {{item.name}}
      <ul>
        <li *ngFor="let car of item.list">
          {{car.title}}----{{car.price}}
        </li>
      </ul>
    </li>
  </ul>
复制代码


效果如下:


image.png


trackBy*ngFor

比如有这样一个例子:


import{ Component } from '@angular/core';
@Component({
 selector: 'trackBy-test',
 template: `
 <ul><li *ngFor="let item of items;>{{item.name}}</li></ul>
 <button (click)="getItems()">Get Items</button>
 `
})
export class TrackByCmp{
 items: any[]=[];
 constructor(){
  this.items = [{id:'1',name:'Tom'},{id:'2',name:'Jerry'},{id:'3',name:'Kitty'}];
 }
 getItems(){
  this.items = [{id:'1',name:'Tom'},{id:'2',name:'Jerry'},{id:'4',name:'Mac'},{id:'5',name:'John'}];
 }
}
复制代码


有时你会需要改变这个集合,比如从后端接口返回了新的数据。那么问题来了,Angular 不知道怎么跟踪这个集合里面的项,不知道哪些该添加哪些该修改哪些该删除。结果就是,Angular 会把该集合里的项全部移除然后重新添加。就像这样:


3.jpg


这样做的弊端是会进行大量的 DOM 操作,而 DOM 操作是非常消耗性能的。


那么解决方案是,为*ngFor 添加一个 trackBy 函数,告诉 Angular 该怎么跟踪集合的各项。trackBy 函数需要两个参数,第一个是当前项的 index,第二个是当前项,并返回一个唯一的标识,就像这样:


import{ Component } from '@angular/core';
@Component({
 selector: 'trackBy-test',
 template: `
 <ul><li *ngFor="let item of items;trackBy: trackByIndex">{{item.name}}</li></ul>
 <button (click)="getItems()">Get Items</button>
 `
})
export class TrackByCmp{
 items: any[]=[];
 constructor(){
  this.items = [{id:'1',name:'Tom'},{id:'2',name:'Jerry'},{id:'3',name:'Kitty'}];
 }
 getItems(){
  this.items = [{id:'1',name:'Tom'},{id:'2',name:'Jerry'},{id:'4',name:'Mac'},{id:'5',name:'John'}];
 }
trackByIndex(index, item){
  return index;
 }
}
复制代码


修改之后,Angular 就知道哪些项变动了:


1.jpg


关于 trackBy 的更多讲解可以参考:Angular-使用好NgForOf的trackBy带来性能上的提升


NgSwitch和NgIf


首先需要在 argular01.component.ts 中定义相关数据内容:


nums: any[] = [111, 222, 333];
flag = false;
order = 1;
复制代码


html 文件内容如下:


<h3>循环,显示数据的索引</h3>
  <div>
    <ul>
      <li *ngFor="let item of nums; let key =index">
        <span *ngIf="key == 1" class="red">{{key+1}}----{{item}}</span>
        <span *ngIf="key != 1">{{key+1}}----{{item}}</span>
      </li>
    </ul>
  </div>
  <br>
  <h3>判断</h3>
  <div *ngIf="flag">
    <p>我是一个P标签</p>
  </div>
  <div *ngIf="!flag">
    <p>我是一个PP标签</p>
  </div>
  <br>
  <h3>NgSwitch</h3>
  <span [ngSwitch]="order">
    <p *ngSwitchCase="1">
      1111111111
    </p>
    <p *ngSwitchCase="2">
      2222222222222
    </p>
    <p *ngSwitchDefault>
      00000000000
    </p>
  </span>
复制代码


上述内容除了介绍 ngIf 和 ngSwitch 的用法,还提到关于循环索引的定义(索引从0开始),同 ngIf 配合使用。


网页效果图如下:


image.png


NgClass和NgStyle


ngClass 同时添加或删除几个 CSS 类。


<div>
  <div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div>
  <div [ngClass]="isSpecial ? 'special' : ''">This div is special</div>
  <div [class]="isSpecial ? 'special2' : ''">This div is special</div>
</div>
复制代码


考虑一个 setCurrentClasses() 组件方法,该方法设置一个组件属性 currentClasses,该对象具有一个根据其他三个组件属性的 true / false 状态来添加或删除三个 CSS 类的对象。该对象的每个键(key)都是一个 CSS 类名。如果要添加上该类,则其值为 true,反之则为 false


home2.component.ts


canSave = true;
  isUnchanged = true;
  isSpecial = true;
  constructor() { }
  ngOnInit(): void {
    this.setCurrentClasses();
  }
  setCurrentClasses() {
    this.currentClasses = {
      'saveable': this.canSave,
      'modified': !this.isUnchanged,
      'special': this.isSpecial
    };
  }
复制代码


CSS 样式:


.saveable{
  background-color: blue;
}
.modified{
  font-size: 21px;
}
.special{
  font-weight: 200;
}
.special2{
  font-weight: 200;
}
复制代码


页面测试:


1.jpg


从上述例子可以看出,当添加单个类时,使用类绑定和 Ngclass 效果是一致的。所以官方文档推荐: 要添加或删除单个类,请使用类绑定而不是 NgClass


使用 NgStyle 根据组件的状态同时动态设置多个内联样式。


<div [ngStyle]="currentStyles">
    This div is initially italic, normal weight, and extra large (24px).
  </div>
  <div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">
    This div is x-large or smaller.
  </div>
复制代码


下面的例子是一个 setCurrentStyles() 方法,它基于该组件另外三个属性的状态,用一个定义了三个样式的对象设置了 currentStyles 属性。


currentStyles: any = {};
  canSave = true;
  isUnchanged = true;
  isSpecial = true;
  constructor() { }
  ngOnInit(): void {
    this.setCurrentStyles();
  }
  setCurrentStyles() {
    // CSS styles: set per current state of component properties
    this.currentStyles = {
      'font-style': this.canSave ? 'italic' : 'normal',
      'font-weight': !this.isUnchanged ? 'bold' : 'normal',
      'font-size': this.isSpecial ? '24px' : '12px'
    };
  }
复制代码


页面测试:


1.jpg


同 ngClass 一样,官方文档同样推荐设置单个样式值采用样式绑定,设置多个内联样式,请使用 NgStyle 指令 。


管道


管道是格式化字符串、金额、日期和其它显示数据的好办法

Angular 自带了很多管道,比如 date 管道和 currency 管道,完整的列表参见 Pipes API 列表。你也可以自己定义一些新管道。


birthday.component.ts 文件中设置如下:


import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-birthday',
  templateUrl: '
    <p>The hero's birthday is {{ birthday | date:format }}</p>
    <button (click)="toggleFormat()">Toggle Format</button>
  '
})
export class BirthdayComponent implements OnInit {
  birthday = new Date(1988, 3, 15); // April 15, 1988
  toggle = true; // start with true == shortDate
  constructor() { }
  ngOnInit(): void {
  }
  get format()   { return this.toggle ? 'shortDate' : 'fullDate'; }
  toggleFormat() { this.toggle = !this.toggle; }
}
复制代码


网页展示效果:


image.png


安全导航运算符( `?` )和空属性路径


Angular 安全导航运算符 ? 可以对在属性路径中出现 nullundefined 值进行保护。在这里,如果 itemnull ,它可以防止视图渲染失败。


<p>The item name is: {{item?.name}}</p>
复制代码


如果 itemnull,则视图仍然渲染,但显示的值为空白;您只会看到 “The item name is:” ,后面没有任何内容。


考虑接下来这个带有 nullItem 的例子。


The null item name is {{nullItem.name}}
复制代码


由于没有安全导航运算符,并且 nullItemnull ,因此 JavaScript 和 Angular 会引发空指针错误并中断 Angular 的渲染过程:


content_copyTypeError: Cannot read property 'name' of null.
复制代码


但是,有时在某些情况下,属性路径中的 null 值可能是可接受的,尤其是当该值开始时为空但数据最终会到达时。


使用安全导航运算符 ?,当 Angular 表达式遇到第一个空值时,它将停止对表达式的求值,并渲染出无错误的视图。


绑定语法



数据绑定是一种机制,用来协调用户可见的内容,特别是应用数据的值。 虽然也可以手动从 HTML 中推送或拉取这些值,但是如果将这些任务转交给绑定框架,应用就会更易于编写、阅读和维护。 您只需声明数据源和目标 HTML 元素之间的绑定关系就可以了,框架会完成其余的工作。


Angular 提供了多种数据绑定方式。绑定类型可以分为三类,按数据流的方向分为:

  • 数据源到视图
  • 视图到数据源
  • 双向:视图到数据源到视图


1.jpg


绑定类型与绑定目标


数据绑定的目标是 DOM 中的对象。 根据绑定类型,该目标可以是 Property 名(元素、组件或指令的)、事件名(元素、组件或指令的),有时是 Attribute 名。下表中总结了不同绑定类型的目标。 关于这一部分会结合例子进行演示,没有固定篇幅进行讲解,详细内容可以参考:Angular模块语法


2.jpg


目录
相关文章
|
7月前
|
前端开发 JavaScript
通过单步调试的方式学习 Angular 中带有选择器的内容投影使用方式
通过单步调试的方式学习 Angular 中带有选择器的内容投影使用方式
47 0
|
7月前
|
存储 JavaScript 前端开发
通过单步调试的方式学习 Angular 中 TView 和 LView 的概念
通过单步调试的方式学习 Angular 中 TView 和 LView 的概念
46 1
|
11月前
|
设计模式 JavaScript 前端开发
学习Angular的编程之旅
学习Angular的编程之旅
|
缓存 前端开发 JavaScript
Javascript学习-angular开发环境搭建及新建项目并运行
Javascript学习-angular开发环境搭建及新建项目并运行
85 0
Javascript学习-angular开发环境搭建及新建项目并运行
|
前端开发 JavaScript API
Angular与Rxjs学习
Angular与Rxjs学习
119 0
Angular与Rxjs学习
|
前端开发 JavaScript 网络架构
Angular基础知识学习(三)
Angular基础知识学习(三)
129 0
Angular基础知识学习(三)
|
前端开发 JavaScript 安全
Angular基础知识学习(二)下
Angular基础知识学习(二)下
109 0
Angular基础知识学习(二)下
|
JavaScript 开发者
Angular基础知识学习(二)上
Angular基础知识学习(二)上
102 0
Angular基础知识学习(二)上
|
JavaScript
Angular基础知识学习(一)下
Angular基础知识学习(一)下
156 0
Angular基础知识学习(一)下
|
3天前
|
存储 前端开发 API
浅谈 Angular 应用前端消息显示机制的一个实际需求
浅谈 Angular 应用前端消息显示机制的一个实际需求
13 0