Angular知识点梳理二

目录

模板

模板语法混淆点梳理

Attribute绑定

[(ngModel )]双向绑定

生命周期方法(钩子方法)

指令

说明

自定义属性指令

结构指令

管道


 

模板

组件中的模板有两种表现形式。

内联模板=>在@Component装饰器中通过template指定使用`符号(ES6中的提出的模板字符串)来进行字符串组装,注意不是'单引号。

模板文件=>在@Component装饰器中可以通过templateUrl指定,地址为对应的html文件的相对路径地址。

模板语法混淆点梳理

模板语法说白了就是怎么绑定数据,要理解绑定数据首先需要搞懂两个概念,什么是Html的 attribute?什么是DOM的property?在传统的赋值的方式中我们需要通过操作DOM来获取Html元素的attribute然后给它赋值,在Angular中我们绑定数据赋值其实绑定的不是attribute而是绑定的property,换句话说attribute其实不会变是固定的,而你设置的具体值是动态的是需要变的。比如<a [attribute]="变量">,我们关注的点是在变量上而不是attribute上。这也是为什么在MVVP模式下要弃用JQuery的原因,要尽量避免直接操作DOM元素,绑定对于数据来说已经够用了,除非你要一些比较酷炫的效果,比如基于canvas/svg搞一些事情的时候,操作DOM还是必不可免的。

上面这段话解释有人反映不太懂,理论不说了就来点直白的吧

我的html中有这么个input,当我用直接用DOM的property赋值的时候,尽管页面上显示的值已经变了,但它的属性值依然不会变,依然是渲染时被初始化的值。

Attribute绑定

是不是很乱,上面刚说完不是attribute,就又来了个attribute绑定,其实这是特例,CSS类绑定与样式绑定都属于Attribute绑定,Attribute绑定是比较特殊的场景,应用于DOM的property不存在的时候,比如td标签的colspan。

[(ngModel )]双向绑定

标准的双向绑定代表,其实是个语法糖,以下是演变过程。

@Component({
    selector: 'test'
    template:`
            <div>
                <button (click)="change()" value="change">
            </div>
        `
})
export class demo{
    @Input() name: string;
    @Output() nameChange: new EventEmitter<string>();
    
    change(name){
        this.name = name;
        this.nameChange.emit(this.name)
    }
}

以上点击button触发change进而触发nameChange


-------------------------------------------------------------------------
<test [name]="currentName" (nameChange)="currentName=$event"></test>

以上引用test组件,为其传入name属性值为currentName,同时接受nameChange事件并把接受到的参数赋值给currentName


-------------------------------------------------------------------------
<test ([name])="currentName"></test>

以上为Angualr提供的语法糖写法

以上只是推演的过程用于理解而已,针对input中的[()]其实是依靠ngModel指令,一直对外Angular隐藏了这些细节,所以如果需要使用input标签内的双向绑定,一定要引入FormsModule模块不然不会生效,因为ngModel执行不生效。

 

生命周期方法(钩子方法)

生命周期方法指的是组件的创建到销毁这段时间内的,暴露出来关键时刻的方法。什么时候会触发那?在Angular中组件新建,更新,销毁时都会触发。对于销毁是组件要从DOM中移除之前会销毁。关于方法的执行顺序如下。

Peek-a-boo

指令

说明

什么是指令?其实就是一个呗@Directive修饰器所修饰的类,被挂载到元素的标签内,类似于标签的属性。

指令有什么用,什么时候用指令?其实指令是用来修改DOM的样式和行为,或者是用来操作DOM元素,避免咱们在写代码的时候直接调用DOM Api来直接操作DOM。

指令都有什么类型?常见的指令分三类属性指令,结构指令,和最通用的组件指令(ng-template)。

自定义属性指令

import { Directive, ElementRef, HostListener, Input } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {

  constructor(private el: ElementRef) { }

  @Input() defaultColor: string;

  @Input('appHighlight') highlightColor: string;

  @HostListener('mouseenter') onMouseEnter() {
    this.highlight(this.highlightColor || this.defaultColor || 'red');
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.highlight(null);
  }

  private highlight(color: string) {
    this.el.nativeElement.style.backgroundColor = color;
  }
}


---------------------------------------------------------------------------------
<p [appHighlight]="color" defaultColor="violet">

结构指令

*ngIf,*ngFor,ngSwitch揭秘,*是一个语法糖,本质是ng-template,*ngIf => <ng-template [ngIf]="xxx"></ng-template>。

ng-container,是一个分组元素,不会被真正渲染到DOM中,在Angualr中的作用类似于JS中的花括号,它不会破坏DOM的样式和布局,对于一些场景下需要一个外层的包装(没有合适的宿主元素)来执行一些指令的时候很有用。

<select [(ngModel) = "xxx"]
    <ng-container *ngFor="let item of heroes>
        <option [ngValue]="item">{{item}}</option>
    </ng-container>
</select>

自定义结构指令

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({ selector: '[appUnless]'})
export class UnlessDirective {
  private hasView = false;

  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef) { }

  @Input() set appUnless(condition: boolean) {
    if (!condition && !this.hasView) {
      this.viewContainer.createEmbeddedView(this.templateRef);
      this.hasView = true;
    } else if (condition && this.hasView) {
      this.viewContainer.clear();
      this.hasView = false;
    }
  }
}


---------------------------------------------------------------------------
<p *appUnless="condition">Show this sentence unless the condition is true.</p>

<ng-template [appUnless]="condition">
  <p class="code unless">
    (A) &lt;ng-template [appUnless]="condition"&gt;
  </p>
</ng-template>

管道

自定义管道

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({name: 'exponentialStrength'})
export class ExponentialStrengthPipe implements PipeTransform {
  transform(value: number, exponent: string): number {
    let exp = parseFloat(exponent);
    return Math.pow(value, isNaN(exp) ? 1 : exp);
  }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值