博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Angular-个人整理
阅读量:6705 次
发布时间:2019-06-25

本文共 10083 字,大约阅读时间需要 33 分钟。

  1. 单向从数据源到视图
{
{expression}}[target]="expression"bind-target="expression"复制代码

单向从视图到数据源

(target)="statement"on-target="statement"复制代码

双向

[(target)]="expression"bindon-target="expression"复制代码
  1. DOM property 的值可以改变;HTML attribute 的值不能改变。

    Angular 的世界中,attribute 唯一的作用是用来初始化元素和指令的状态。
    当进行数据绑定时,只是在与"元素和指令"的 "property 和事件"打交道,而 attribute 就完全靠边站了。

  2. 如果忘了加方括号Angular 会把这个表达式当做字符串常量看待,并用该字符串来初始化目标属性。

    下面这个例子把 HeroDetailComponentprefix 属性初始化为固定的字符串"1+1",而不是模板表达式"2"。Angular 设置它,然后忘记它。

复制代码

作为对比,[hero] 绑定是组件的 currentHero 属性的活绑定,它会一直随着更新

  1. 插值表达式 {
    {...}}
    ,先对双花括号中的表达式求值,再把求值的结果转换成字符串
    实际上,在渲染视图之前,Angular 把这些插值表达式翻译成了相应的属性绑定。
  • 注意:但数据类型不是字符串时,就必须使用属性绑定了。

is the interpolated image.

is the property bound image.

复制代码
  1. 不管是插值表达式还是属性绑定,都不会允许带有 script 标签的 HTML 泄漏到浏览器中,二者都只渲染没有危害的内容。
src/app/app.component.ts    evilTitle = 'Template Syntax';src/app/app.component.html      

"{

{evilTitle}}" is the interpolated evil title.

"" is the property bound evil title.

复制代码
  1. attribute 绑定
    一般情况下,我们通过属性绑定来设置元素的属性property,而不用字符串设置元素的attribute
    但考虑 ARIASVGtable 中的 colspan/rowspanattribute。 它们是纯粹的 attribute没有对应的属性可供绑定。 如果想写出类似下面这样的东西,就会暴露出痛点了:
Three-Four复制代码

会得到这个错误:

Template parse errors: Can't bind to 'colspan' since it isn't a known native property
方括号中的部分不是元素的属性名,而是由attr前缀,一个点 (.)attribute 的名字组成

One-Two复制代码
  1. 双向数据绑定 ( [(...)] )

双向绑定语法实际上是属性绑定和事件绑定的语法糖。

  1. 内置属性型指令
  • a.通过绑定到 NgClass,可以同时添加或移除多个类。 把 ngClass 绑定到一个 key:value 形式的控制对象valueboolean值)

src/app/app.component.html

This div is initially saveable, unchanged, and special
复制代码

src/app/app.component.ts

currentClasses: {};    setCurrentClasses() {      // CSS classes: added/removed per current state of component properties      this.currentClasses =  {        'saveable': this.canSave,        'modified': !this.isUnchanged,        'special':  this.isSpecial      };    }复制代码
  • b.通过绑定NgStyle设置多个内联样式。NgStyle 需要绑定到一个 key:value 控制对象。 src/app/app.component.html
This div is initially italic, normal weight, and extra large (24px).
复制代码

src/app/app.component.ts

currentStyles: {};    setCurrentStyles() {      // CSS styles: set per current state of component properties      this.currentStyles = {        'font-weight': 'bold',      };    }复制代码
  1. 模板输入变量和模板引用变量
  • 模板输入变量
    hero 前的 let 关键字创建了一个名叫 hero 的模板输入变量。 这个变量的范围被限制在所重复模板的单一实例上。事实上,你可以在其它内置结构型指令中使用同样的变量名。
  • 模板引用变量
    #phone 的意思就是声明一个名叫 phone 的变量来引用 <input> 元素。 模板引用变量的作用范围是整个模板。不要在同一个模板中多次定义同一个变量名,否则它在运行期间的值是无法确定的。
复制代码
  1. 你总是可以在"组件自己的模板"中绑定到组件的公共属性,而不用管它们是否输入(Input)属性或输出(Output)属性。 但Angular 需要@Input()@Output()装饰器来标记出那些允许被外部组件绑定到的属性。 声明输入与输出属性:
@Input()  hero: Hero;@Output() deleteRequest = new EventEmitter
();复制代码

另外:@Input get/set写法

_oprType: string ='VIEW';@Input("oprType")get oprType(){    retrun this._oprType;}set oprType(oprType){    this._oprType = oprType;    ...//其他逻辑处理}复制代码
  1. json 管道对调试绑定特别有用:
src/app/app.component.html (pipes-json)      
{
{currentHero | json}}
复制代码

它生成的输出是这样的:

{ "id": 0, "name": "Hercules", "emotion": "happy",  "birthdate": "1970-02-25T08:00:00.000Z",  "url": "http://www.imdb.com/title/tt0065832/",  "rate": 325 }复制代码
  1. 生命周期
  • 注意:构造函数在所有的生命周期钩子之前执行

ngOnChanges()-》ngOnInit()-》ngDoCheck()-》ngAfterContentInit()-》ngAfterContentChecked()-》ngAfterViewInit()-》ngAfterViewChecked()-》ngOnDestroy()

ngOnInit 生命周期钩子会在 DOM 更新操作执行前触发

  1. rxjs知识
var subject = new Subject
();subject.next(1);subject.subscribe({ next: (v) => console.log('observerA: ' + v)});//observerA: 1复制代码
  1. 纯(pure)管道与非纯(impure)管道

    默认情况下,管道都是纯的。 Angular 只有在它检测到输入值发生了纯变更时才会执行纯管道。
    纯变更:是指对原始类型值(String、Number、Boolean、Symbol)的更改,或者对对象引用(Date、Array、Function、Object)的更改。
    Angular 会忽略对象内部的更改。 如果你更改了输入日期(Date)中的月份、往一个输入数组(Array)中添加新值或者更新了一个输入对象(Object)的属性,Angular 都不会调用纯管道。
    Angular 会在每个组件的变更检测周期中执行非纯管道。 非纯管道可能会被调用很多次,和每个按键或每次鼠标移动一样频繁。

  2. ElementRef

import { Directive, ElementRef } from '@angular/core';@Directive({  selector: '[appHighlight]'})export class HighlightDirective {    constructor(el: ElementRef) {       el.nativeElement.style.backgroundColor = 'yellow';    }}复制代码

import 语句还从 Angularcore 库中导入了一个 ElementRef 符号。

你可以在指令的构造函数中注入 ElementRef,来引用宿主 DOM 元素。 ElementRef(对视图中某个宿主元素的引用)通过其 nativeElement 属性给了你直接访问宿主 DOM 元素的能力。

  • 注意:允许直接访问 DOM 会导致你的应用在 XSS 攻击前面更加脆弱。当需要直接访问 当需要直接访问 DOM 时,请把本 API 作为最后选择

优先使用 Angular 提供的模板和数据绑定机制。 或者你还可以看看 Renderer2(实现自定义渲染器),它提供了可安全使用的 API —— 即使环境没有提供直接访问原生元素的功能。

import { Directive, ElementRef, Renderer2 } from '@angular/core';@Directive({  selector: '[appHighlight]'})export class HighlightDirective {    constructor(el: ElementRef, private renderer: Renderer2) {       //el.nativeElement.style.backgroundColor = 'yellow';       this.renderer.setStyle(this.el.nativeElement, "backgroundColor", 'yellow');    }}复制代码

  1. HostListener把一个事件绑定到一个宿主监听器,并提供配置元数据。
@HostListener('mousedown') onMouseEnter() {  this.highlight(this.highlightColor || this.defaultColor || 'red');}复制代码

mousedown要监听的事件。 当mousedown事件发生时,Angular 就会执行所提供的处理器方法onMouseEnter

  1. 你可以根据属性名在绑定中出现的位置来判定是否要加 @Input
    当它出现在等号右侧的模板表达式中时,它属于模板所在的组件,不需要 @Input 装饰器。
    当它出现在等号左边的方括号([ ])中时,该属性属于其它组件或指令,它必须带有 @Input 装饰器。

Highlight me!

复制代码

color 属性位于右侧的绑定表达式中,它属于模板所在的组件。 该模板和组件相互信任。因此 color 不需要 @Input 装饰器。

appHighlight 属性位于左侧,它引用了 HighlightDirective 中一个带别名的属性,它不是模板所属组件的一部分,因此存在信任问题。 所以,该属性必须带 @Input 装饰器。

  1. bootstrap —— 根组件,Angular 创建它并插入 index.html 宿主页面。
  2. 结构型指令中,星号(*)写法是个语法糖,Angular会把它解开成一个 <ng-template> 标记,包裹着宿主元素及其子元素。 Angular 会在真正渲染的时候填充 <ng-template> 的内容,并且把 <ng-template> 替换为一个供诊断用的注释。
({
{i}}) {
{hero.name}}
复制代码
  • 注意:如果没有使用结构型指令,而仅仅把一些别的元素包装进 <ng-template> 中,那些元素就是不可见的(被注释掉了)。
  1. 每个宿主元素上只能有一个结构型指令。比如:*ngFor*ngIf 不能放在同一个宿主元素上。
    有一个简单的解决方案:把 *ngFor 放在一个"容器"元素上,再包装进 *ngIf 元素。 这个元素可以使用ng-container,以免引入一个新的 HTML 层级。
复制代码

Angular<ng-container> 是一个分组元素,但它不会污染样式或元素布局,因为 Angular 压根不会把它放进 DOM 中。

template: 
class: @ViewChild("toolbarTemplate") toolbarTemplate: TemplateRef
简化写法:
复制代码

该指令用于基于已有的 TemplateRef 对象,插入对应的内嵌视图。在应用 NgTemplateOutlet 指令时,我们可以通过 [ngTemplateOutletContext] 属性来设置 EmbeddedViewRef 的上下文对象。绑定的上下文应该是一个对象,此外可通过 let语法来声明绑定上下文对象属性名。

  1. 表达式中的上下文变量是由"模板引用变量#aa"、"模板输入变量let bb"和"组件的成员cc"叠加而成的。

    优先级:模板输入变量>模板引用变量>指令的上下文变量>组件类的实例

  2. 模板表达式不能引用全局命名空间中的任何东西,比如windowdocument。它们也不能调用console.logMath.max。它们只能引用表达式上下文中的内容。

  3. 声明式组件和入口组件:

    声明式组件会在模板中通过组件声明的selector(比如<cmb></cmb>)加载组件。
    入口组件entryComponents主要有3类:

  • @NgModule中的bootstrap声明的根组件
  • 路由配置的组件
  • 动态组件
  1. exports
    在模块angModuleexports出一组组件、指令和管道
    -》模板b导入了模块a
    -》模块b下的所有组件的模板,都可以使用模块angModuleexports出的组件、指令和管道
  2. 父子组件交互
{
{timer.seconds}}
复制代码

这个本地变量方法#timer是个简单便利的方法。但是它也有局限性,因为父组件-子组件的连接必须全部在父组件的html模板中进行。父组件本身的ts代码对子组件没有访问权。

父组件ts需要这种访问时,可以把子组件作为 ViewChild,注入到父组件里面。@ViewChild('timer') timer;

  1. 内容投影ng-content

父组件页面parent.html

abcde
复制代码

被父组件包含的子组件标签页面attchment-upload.html

-- begins --
-- ends --
`复制代码

输出:

-- begins --abcde-- ends --复制代码

以上<ng-content> 标签是父组件页面中外来内容的占位符。 它指明在子组件标签页面的哪里插入这些父组件的外来内容abcde

注意不要在组件标签的内部放任何内容 —— 除非你想把这些内容投影进这个组件中。

  1. NgTemplateOutlet基于已有的TemplateRef 对象,插入对应的内嵌视图。
Hello
复制代码

或者

contentTemplate:TemplateRef
this.contentTemplate=...//TemplateRef就是对应html中的ng-template标签复制代码
  1. ngIf写法
...
...
复制代码

30.ngTemplateOutletContext

// 通过 [ngTemplateOutletContext] 属性来设置 EmbeddedViewRef:commonBodyTemplate的上下文对象
//若 let 语法未绑定任何属性名(let-col),则上下文对象中 $implicit 属性,对应的值col将作为默认值。
{
{rowIndex+1}}
{
{(rowData[col.field]||"--")+(rowData["attachSizeUnit"]||"")}}
{
{rowData[col.field]||""}}
{
{rowData[col.field]||"--"}}
{
{rowData[col.field]||"--"}}
复制代码

在父页面中嵌入<app-attachment></app-attachment>

报错:"app-attachment" is not a unknown element.
原因:app-attachment子页面模板对应的ts组件没有包括在父页面所在的module中。

32.@Input('companyId') companyId: string; 子组件的初始化constructor取不到companyId值,ngOnInit()可以 所以初始化放在ngOnInit中。

33.响应式表单

this.formGroup=fb.group({        contractid:["123",[Validators.required]],});this.theDetailGroup.get("finProductName").setValue(this.finProductName);this.formGroup.get("docmentId").valueChanges.subscribe(value=>{          if(this.existList.findIndex(item=>item.docmentId==value)>-1){            this.formGroup.get("docmentId").setErrors({duplicate:true});          }        });        this.formGroup.get("docmentId").value; 复制代码

34.this.fb.group({}) 响应式表单控件绑定,应该在生命周期之前,即constructor构造函数中初始化。因为如果放在ngOnInit中绑定,在表单初始化前对表单进行赋值操作,会报错。

35.自定义模块中exports使用

将附件声明到公用模块

import { NgModule } from '@angular/core';import { CommonModule} from '@angular/common';import { AttachmentComponent } from './attachment.component';@NgModule({  imports: [    CommonModule,  ],  exports:[    CommonModule,    AttachmentComponent  ],  providers:[],  declarations: [    AttachmentComponent  ],  entryComponents:[    AttachmentComponent  ]})export class SharedModule { }复制代码

宿主组件所在的module中引入公共模块

import { NgModule } from '@angular/core';import { CommonModule } from '@angular/common';import { SharedModule } from 'src/app/shared';@NgModule({  declarations: [     ],  imports: [    CommonModule,    SharedModule  ],  entryComponents:[]})export class MineModule { }复制代码

36.自定义双向数据绑定

  • 父组件
复制代码
  • 子组件app-base.ts
_companyId = '';  @Output() companyIdChange = new EventEmitter();  @Input('companyId')  get companyId() {    return this._companyId;  }  set companyId(companyId) {    this._companyId = companyId;    this.companyIdChange.emit(companyId);  }复制代码

注意:属性名 + Change是双向绑定中Output的固定写法

37.在使用一些第三方的组件的时候,要修改组件的样式。 这种情况下使用:

:host ::ng-deep .className{    新的样式......}复制代码

38.要在html直接使用某个变量。ts中可以不要定义这个变量,直接get

html:
ts:get isStatusOkey() {return this.baseInfoConfig.baseInfoData['lpIndentifyStatus'] !== 'OKAY';}html:
ts:get attachmentTypeList() {return this.attachService.getAttachmentTypeList();}复制代码

转载地址:http://fcdlo.baihongyu.com/

你可能感兴趣的文章
H264 介绍[1]
查看>>
将大数组里面的小数组平行展开的实现(Making a flat list out of list of lists in Python)...
查看>>
echarts 显示下载按钮,echarts 自定义按钮,echarts 添加按钮
查看>>
HDU 1556 Color the ball
查看>>
Zabbix使用总结
查看>>
面试题2(选择题)
查看>>
C# Label显示多行文本及换行(WinForm/WebForm)
查看>>
java SSL Server
查看>>
Finding Similar Items 文本相似度计算的算法——机器学习、词向量空间cosine、NLTK、diff、Levenshtein距离...
查看>>
20:球弹跳高度的计算
查看>>
Discuz常见小问题-如何修改自己发布的帖子
查看>>
[Angular] Using directive to create a simple Credit card validator
查看>>
C++11 右值引用和转移语义
查看>>
C语言 · 字符串的展开
查看>>
Exception的ToString()方法究竟返回的是什么
查看>>
linux下的静态库与动态库
查看>>
java-JProfiler(五)-监控性能
查看>>
百科知识 tar文件如何打开
查看>>
android设计的布局在阿拉伯语下界面错乱的解决方法
查看>>
获取断面线的范围
查看>>