Angular学习笔记之-8.指令

内置指令

Angular 提供了两种内置指令属性型指令和结构型指令

最常见的属性型指令如下:

NgClass —— 添加和删除一组 CSS 类。

NgStyle —— 添加和删除一组 HTML 样式。

NgModel —— 将数据双向绑定添加到 HTML 表单元素。

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

1.相关代码

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

        @Component({
        selector: 'app-built-in-ng-class',
        template: `
            <h1>app-built-in-ng-class</h1>
            /* 绑定单个值, 官方建议用类绑定 */
            <h3 [ngClass]="colorRed ? 'color-red' : ''">app-built-in-ng-class</h3>
            <br>
            <h3 [class.font-size]="isFontSize">app-built-in-ng-class</h3>
            <button (click)="colorRed = !colorRed">Change ColorRed Value</button>
            <br>
            /* 绑定多个值, 官方建议用类绑定*/
            <h3 [ngClass]="{'color-red':colorRed,'font-size':isFontSize}">app-built-in-ng-class</h3>
            <h3 [ngClass]="isAddClass">app-built-in-ng-class</h3>

        `,
        styles: [
            `
            .color-red {
                color: red;
            }

            .font-size {
                font-size: 30px;
            }
            `,
        ],
        })
        export class DirectivesBuiltInNgClassComponent {
        colorRed: boolean = true;
        isFontSize : boolean = true
        isAddClass : any = {
            'color-red' : true,
            'font-size' : true
        }
        }

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

1.相关代码

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

        @Component({
        selector: 'app-built-in-ng-style',
        template: `
            <h1>app-built-in-ng-style</h1>
            /* 利用 样式绑定  绑定单个值, 官方建议用样式绑定*/
            <h3 [style.color]="colorRed">app-built-in-ng-style</h3>

            /* 利用 指令绑定*/
            <h3 [ngStyle]="{color:'green'}">app-built-in-ng-style</h3>
            /* 绑定多个值,  利用 指令绑定*/ 
        
            <h3 [ngStyle]="{color:'green',fontSize:'20px'}">app-built-in-ng-style</h3>
            <h3 [ngStyle]="ngStyle">app-built-in-ng-style</h3>
        `,
        
        })
        export class DirectivesBuiltInNgStyleComponent {
        colorRed: string = 'red';
        ngStyle: any = {
            color:"blue",
            fontSize : "20px"
        };
        
        }

[(ngModel)] :双向绑定 NgModel 指令允许你显示数据属性并在用户进行更改时更新该属性

1.相关代码

import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';

        @Component({
        selector: 'app-built-in-ng-model',
        template: `
            <h1>app-built-in-ng-model</h1>
            <h3>{{ inputName }}</h3>
            <input [(ngModel)]="inputName" />

            <br />
            /* (ngModelChange)="inputName = input.value" */
            <br />
            <input
            #input
            [ngModel]="inputName"
            (ngModelChange)="inputName = input.value"
            />

            <br />
            /* (ngModelChange)="inputName = $event.target.value" */
            <br />
            <input
            #input
            [ngModel]="inputName"
            (ngModelChange)="inputName = $event.target.value"
            />

            <app-built-in-ng-model-child
            [(inputName)]="inputName"
            ></app-built-in-ng-model-child>
        `,
        })
        export class DirectivesBuiltInNgModelComponent {
            private _inputName! : string
        get inputName(){
            return this._inputName
        };
        set inputName(value){
            console.log('value:', value)
            this._inputName = value
        }
        }

        @Component({
        selector: 'app-built-in-ng-model-child',
        template: `
            <h1>app-built-in-ng-model-child</h1>
            <h3>{{ inputName }}</h3>

            <input #inputChild (input)="change(inputChild.value)" />
        `,
        })
        export class DirectivesBuiltInNgModelChildComponent implements OnInit {
        @Input() inputName!: string;
        @Output() inputNameChange = new EventEmitter<string>();

        ngOnInit() {}

        change(value: string) {
            this.inputNameChange.emit(value);
        }
        }


内置结构型指令

NgIf —— 从模板中创建或销毁子视图。

NgFor —— 为列表中的每个条目重复渲染一个节点。

NgSwitch —— 一组在备用视图之间切换的指令。

带 trackBy 的 *ngFor

1.相关代码

  /*src/app/app.component.html*/
    content_copy
    <div *ngFor="let item of items; trackBy: trackByItems">
        ({{item.id}}) {{item.name}}
    </div>

NgSwitch 指令

1.相关代码

 /* src/app/app.component.html*/
   <div [ngSwitch]="currentItem.feature">
       <app-stout-item    *ngSwitchCase="'stout'"    [item]="currentItem"></app-stout-item>
       <app-device-item   *ngSwitchCase="'slim'"     [item]="currentItem"></app-device-item>
       <app-lost-item     *ngSwitchCase="'vintage'"  [item]="currentItem"></app-lost-item>
       <app-best-item     *ngSwitchCase="'bright'"   [item]="currentItem"></app-best-item>
       <app-unknown-item  *ngSwitchDefault           [item]="currentItem"></app-unknown-item>
   </div>

自定义属性指令

1.相关代码

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

        @Directive({
        selector: '[appHighlight]',
        })
        export class HighlightDirective {
        el: ElementRef<any>;

        /* input属性别名,不然在宿主元素上要绑定两个属性 
            <p appHighlight  [hightColor] = "color">app-hight-directive</p>
        */
        @Input('appHighlight') hightColor: string | undefined ;
        @Input() defaultColor!: string;

        @HostListener('mouseenter') onMouseEnter() {
            this.color(this.hightColor || this.defaultColor || 'red');
        }

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

        @HostListener('click') onClick() {
            console.log('22334:', 22334);
        }

        constructor(el: ElementRef) {
            this.el = el;
            /* 建议不必要这样做

                1.必须正确的书写事件监听器。

                2.当指令被销毁的时候,必须拆卸事件监听器,否则会导致内存泄露。

                3.必须直接和 DOM API 打交道,应该避免这样做。
            
            */

            // el.nativeElement.onmouseover = function(){

            //     el.nativeElement.style.color = 'red';
            // }

            // el.nativeElement.onmouseout = function(){

            //     el.nativeElement.style.color = '';
            // }
        }

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

        @Component({
        selector: 'app-hight-directive',
        template: `
            <h1>将鼠标移入到文字上</h1>
            /* 高亮颜色 和 默认高亮颜色 都不传 */
            <p [appHighlight]>app-hight-directive</p>
            /* 只传 高亮颜色 */
            <p [appHighlight]="color">app-hight-directive</p>
            /* 只传 默认高亮颜色 */
            <p appHighlight [defaultColor]="defaultColor">app-hight-directive</p>
            / * ngNonBindable  可以让 Angular 不对模板中的表达式进行求值*/
            <p ngNonBindable>This should not evaluate: {{ evaluate() }}</p>
            <p>This should not evaluate: {{ evaluate() }}</p>
            / * ngNonBindable  可以让 Angular 不对模板中的表达式进行求值
                仍然允许指令作用于受 ngNonBindable 影响的元素上*/
            <p ngNonBindable  [appHighlight]="color">This should not evaluate: {{ evaluate() }}</p>
        `,
        })
        export class HighlightDirectiveComponent {
        color: string = 'yellow';
        defaultColor: string = 'green';

        evaluate() {
            return 3 + 4;
        }
        }

        /* 附录:为什么要加@Input?

            无论哪种方式,@Input 装饰器都告诉 Angular,该属性是公共的,并且能被父组件绑定。 如果没有 @Input,Angular 就会拒绝绑定到该属性。

            但你以前也曾经把模板 HTML 绑定到组件的属性,而且从来没有用过 @Input。 差异何在?

            差异在于信任度不同。 Angular 把组件的模板看做从属于该组件的。 组件和它的模板默认会相互信任。 这也就是意味着,组件自己的模板可以绑定到组件的任意属性,无论是否使用了 @Input 装饰器。

            但组件或指令不应该盲目的信任其它组件或指令。 因此组件或指令的属性默认是不能被绑定的。 从 Angular 绑定机制的角度来看,它们是私有的,而当添加了 @Input 时,Angular 绑定机制才会把它们当成公共的。 只有这样,它们才能被其它组件或属性绑定。

            你可以根据属性名在绑定中出现的位置来判定是否要加 @Input。

            当它出现在等号右侧的模板表达式中时,它属于模板所在的组件,不需要 @Input 装饰器。

            当它出现在等号左边的方括号([ ])中时,该属性属于其它组件或指令,它必须带有 @Input 装饰器。


            试用此原理分析下列范例:

            <p [appHighlight]="color">Highlight me!</p>

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

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

        */

自定义结构指令

1.相关代码

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

        @Directive({
        selector: '[myNgIf]',
        })
        export class MyNgIfDirective {
        @Input('myNgIf') set showFlg(value:boolean){
            /* value是绑定的值 templateRef是宿主对象*/
            console.log('this.templateRef:', this.templateRef)
            if(value){
            this.viewContainer.createEmbeddedView(this.templateRef)
            }else{
            this.viewContainer.clear();
            }

        };

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


        }

        @Component({
        selector: 'app-my-ng-if-directive',
        template: `
            <h1>app-my-ng-if-directive</h1>
            <p *myNgIf="show">app-my-ng-if-directive</p>
            <button (click)="show = !show">my-ng-if-directive show button</button>
        `,
        })
        export class MyNgIfComponent {
        show: boolean = true;
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值