Angular Tracy 小笔记 数据绑定,指令

2023-10-26

数据绑定

 

  • 数据绑定的本质,就是我们的通讯操作
  • 左边的业务逻辑.ts 想传递数据给模板显示 .html 可以通过: 插件表达式 {{data}}, 属性绑定 [property]="data"
    • 插值表达式 {{data}}
      • 变量调用
        .html 里写 <p>{{tracyName}} 今年 {{tracyAge}} 岁 <p>
        .ts 在 class 里写 export class HerosComponent implements OnInit {
        tracyName:String = '飞飞';
        tracyAge:Number = 18;
        }
      • 函数调用
        .html 里写 <p>{{getTracyName()}} <p>
        .ts 在 class 里写 export class HerosComponent implements OnInit {
        tracyName:String = '飞飞';
        tracyAge:Number = 18;
        getTracyName(){return this.tracyName;}
        }
      • 对字符串本身进行输出 {{'值表达式里写的字会直接输入'}}
    • 属性绑定 [property]="data"
      • 这个属性必须是空间自带的属性,或者我们自定义的属性,不能乱写
      • .html 里写 <button type="button" class="btn btn-primary" [disabled]="shuXingMing">Primary</button>
        .ts 在 class 里写 export class HerosComponent implements OnInit {
        shuXingMing = true;
        constructor() { //构造函数
        setTimeout(() => { //设置一个延时操作
        this.shuXingMing = false;
        }, 2000)
        }
    • 属性绑定 和 差值表达式的区别:
      • 当我们的变量类型是字符串的时候,属性绑定 和 差值表达式是完全一致的。
        <img src="{{src}}" />
        <img [src]="src" /> 我们还是建议这种
      • 当我们的变量是 Boolen, 叠加等, 那么我们就只能使用属性绑定的模式, 否则在 .ts 文件中变量变化的时候, .html 显示的东西不会变
      • <button type="button" class="btn btn-primary" [disabled]="shuXingMing">Primary</button>
        shuXingMing = true;
  • 右边的模板显示 .html 想传递数据给 业务逻辑 .ts 需要通过事件处理, 比如 button 的单击事件
    • 事件处理 (event) = "expression"
    • 单击事件 click
      <input type="button" value="按钮" (click)="info()"/> {{tracyName}}
      .ts 在 class 里写 export class HerosComponent implements OnInit {
      tracyName:String = '飞飞';
      info(){
      this.tracyName = "11";
      }
      }
    • change/input 事件 click
      <input type="text" (change)="info($event)"/> {{tracyName}}
      .ts 在 class 里写 export class HerosComponent implements OnInit {
      tracyName:String = '飞飞';
      info(event:any){
      //console.log(event);//我们就是通过打印这个 event 在控制台里查看到 这个 文本框输入框里的内容是在 target value 里的
      this.tracyName = event.target.value;
      this.tracyName = (<HTMLInputElement>event.target).value; // 这里也可以做一个强制转化操作,效果一样
      }
      }
      changge 事件: 此事件会在元素内容发生改变,且失去焦点的时候触发,既在输入结束后点击回车触发
      input 事件: 此事件会在 value 属性值发生改变时触发,通过js改变value属性值不会触发此事件。 (input 事件的效果很像双向数据绑定,但是双向数据绑定实现的会更多)
  • 双向数据绑定
    • 结合两种模式 [(ngModel)] = "data" 通过 ngModel 的方式将数据进行双向数据绑定
      这里的中括号,代表属性绑定; 小括号代表事件触发; 那么既绑定属性,又绑定事件就代表我们将逻辑层和模板层做了一个双向绑定
    • 双向数据绑定: 变量 tracyName,需在 .ts 文件里的 class 里声明
      Input A : <input type="text" [(ngModel)]="tracyName" /> 这里直接显示 {{tracyName}}
      在使用 input 标签的时候,需要在 app.module.ts 里引入 form 表单组件 FormsModule
      在 "imports:" 对象里加 FormsModule 属性 (加属性之前要往上一个属性的后面加个逗号), 然后在头部加声明 import {FormsModule} from '@angular/forms';
      看起来这里很像 事件绑定,文本框里的内容改变,显示出来的 {{tracyName}} 就会变。
      但是双向数据绑定意味着,如果 {{tracyName}} 的值变了,这个文本框里的东西也会跟着变, 他们是互相的。
      比如说我们加一个上面change 事件写的 Input B: <input type="text" (change)="info($event)"/>
      这个 Input B 的内容改变,Input A 也会跟着变。 但是 Input A 改变 则不会硬性 Input B 里的内容。 这才是双向数据绑定的含义。

指令(Directives)

指令是在 DOM 对象中的一些提示操作,有三种指令

  • 使用模板的组件指令

    组件指令是三个指令中最常见的, 就是调用组件
    .ts 文件的 selector: 'directive-name'
    <directive-name></directive-name>
    <div directive-name></div>
    <div class="directive-name"></div>

  • 结构指令

    • 有一个 * 的前缀 是语法糖的模式
    • 在同一个 html 标签里,不能同时进行多个带有 * 号的指令操作,每次只能一个
    • 通过添加和移除 DOM 元素来改变 DOM 布局
    • 结构指令改变视图的结构,例如 ngfor 和 ngif
    • .ts 文件有个 变量 sectionDisplay: false; 然后有个函数可以改变这个变量; html 中可以用 ngif 来让某个 div, p 等标签不渲染 (注意,这里并不是说给隐藏了,而是根本就不渲染,在鼠标右键控制台"检查"的时候 是看不到这段 code 的)
      <div *ngIf="sectionDisplay"></div>
    • ngif 的判断 *ngIf="sellectTab === 'recipes'"
      多用于 tab 标签切换, 当 sellectTab = recipes 的时候,相对应的 tab content div 就会显示出来
    • 那么有了 ngif, 怎么设定 else 呢?
      <div *ngIf="sectionDisplay; else noServer"> Tips: noServer 名字任意</div>
      这里要先创建一个 ng-template 然后给它加上一个类似ID 一样的东西 #noServer
      <ng-template #noServer><p>else 之后显示的东西 </p></ng-template>
    • ngFor 循环指令与循环索引
      父组件 ts code : servers:['serverTest1','serverTest2','serverTest3'] (如果想添加可以在某个单击事件中写 servers.push(this.变量名))
      父组件 html code: <app-recipes-item *ngFor="let server of servers;"></app-recipes-item> 循环显示子组件
      注意,这里的 servers 是 ts 文件里的数组名; server 是随便起的,叫 aa 也行
    • 给循环设置下标
      <app-recipes-item *ngFor="let aa of servers; let i=index"></app-recipes-item>
      这里的 i 和 aa 就很方便以后使用,传值给子组件或者属性设置了
      比如 : <app-recipes-item *ngFor="let aa of servers; let i=index" [ngStyle]="{backgroundColor: i%2 === 1? '#e0e0e0':'#eee'}"></app-recipes-item>
    • 结构指令的脱糖操作(removed *)
      把指令用方括号阔上, 然后用 ng-template 作为标签
      <div *ngIf="sellectTab === 'recipe'">里面有一堆东西</div>
      <ng-template [ngIf]="sellectTab === 'recipe'">里面有一堆东西</ng-template>

      ngFor 的脱糖
      <app-recipe-item *ngFor="let recipeEL of recipes; let i=index" [item]="recipeEL" [index]="i" (selectItem)="onRecipeSelected(recipeEL)"></app-recipe-item>

      <ng-template ngFor let-recipeEL [ngForOf]="recipeslet-i="index">
      <app-recipe-item [item]="recipeEL" [index]="i" (selectItem)="onRecipeSelected(recipeEL)"></app-recipe-item> </ng-template>
  • 自定义结构指定
    • 创建自定义结构指令 ng g d name
    • <div *ngIf="sellectTab === 'recipe'">结构指定ngIf</div>
      <div *appUnless="sellectTab === 'recipe'">自定义结构指定</div>
      import { Directive, TemplateRef, Input, ViewContainerRef } from "@angular/core";
      @Directive({ selector: "[appUnless]" })
      export class UnlessDirective {
      @Input() set appUnless(condition: boolean) { if (condition) { this.vcRef.createEmbeddedView(this.templateRef); } else { this.vcRef.clear(); } }
      constructor( private templateRef: TemplateRef<any>, private vcRef: ViewContainerRef ) {}
      }
  • 属性指令

    有可能进行数据绑定以及事件绑定
    • 一个 html 标签上可以设置多个 属性指令
    • 更改元素、组件或其他指令的外观或行为,并不更改页面 DOM 结构,即使给隐藏了,它的结构也是可以在鼠标右键控制台"检查"的时候 是看到这段 code 的
    • 属性指令作为元素的属性进行设置,例如通过 ngStyle 可以改变元素的样式
    • 注意这里的 style 属性和正常的 style 不同,是一个驼峰式的写法
      <div [ngStyle]="{backgroundColor: i%2 === 1? '#e0e0e0':'#eee'}"></div>
    • <div [ngStyle]="{backgroundColor: aa}"></div>
      这里的 aa 可以是一个变量名,也可以调用函数 aa(); 都是在 .ts 文件中
    • <div [ngClass]="{aa: serverStage === '离线' }"></div>
      这里的 aa 是 class 名, 冒号后面是判断,条件为真就用这 class aa, 条件为加就不加这个 class aa.
      serverStage 等于 '离线' 的时候 div 用 class="aa"
    • <li [[ngClass]="{'nav-item': true, 'active': sellectTabName === 'recipes'}">Recipes</li>
      多用于 tab 标签切换, navigation 的每个 li 都默认有 nav-item class, 哪个被选中了再加上一个 active class. 这里是 如果 sellectTabName = recipes,相当于<li class="nav-item active">Recipes</li>
  • 自定义属性指令
    • 创建自定义属性 ng g d name
    • 本来后面加 --spec false 是好用的,后来不好用了
    • <p appBasicHighlight>自定义属性使用,可以改变背景颜色</p>

      import { Directive } from "@angular/core";
      import { ElementRef } from "@angular/core";
      import { OnInit } from "@angular/core";
      @Directive({ selector: "[appBasicHighlight]" })
      export class BasicHighlightDirective implements OnInit {
      constructor(private elementRef: ElementRef) {}
      ngOnInit(): void { this.elementRef.nativeElement.style.backgroundColor = "green"; } }
    • <p appBetterHighlight> better 自定义属性使用,可以进行元素的渲染操作</p>

      import { Directive } from "@angular/core"; import { ElementRef, Renderer2 } from "@angular/core";
      import { OnInit } from "@angular/core";
      @Directive({ selector : "[appBetterHighlight]" })
      export class BetterHighlightDirective implements OnInit { constructor(private elRef: ElementRef, private renderer: Renderer2) {}
      ngOnInit(): void { this.renderer.setStyle(this.elRef.nativeElement,'background-color','blue'); } }
    • 指令监听事件 HostListener,如鼠标划过事件,回车事件等
      <p appBetterHighlight> 监听鼠标事件</p>

      import { Directive } from "@angular/core";
      import { ElementRef, Renderer2 } from "@angular/core";
      import { OnInit, HostListener } from "@angular/core";
      @Directive({
      selector: "[appBetterHighlight]"
      })
      export class BetterHighlightDirective implements OnInit {
      constructor(private elRef: ElementRef, private renderer: Renderer2) {}
      //一开始背景颜色是红色
      ngOnInit(): void { this.renderer.setStyle( this.elRef.nativeElement, "background-color", "red" ); }
      //鼠标滑过,背景颜色是蓝色
      @HostListener("mouseenter") mouseover(eventData: Event) { this.renderer.setStyle( this.elRef.nativeElement, "background-color", "blue" ); }
      //鼠标滑走,背景颜色变回白色
      @HostListener("mouseleave") mouseleave(eventData: Event) { this.renderer.setStyle( this.elRef.nativeElement, "background-color", "white" ); } }
    • HostBinding 动态设置元素的属性值
      <p appBetterHighlight> 监听鼠标事件</p>
      @HostBinding('style.backgroundColor') myBackgrounColor:string = "transparent";
      //鼠标滑过,背景颜色是蓝色
      @HostListener("mouseenter") mouseover(eventData: Event) { this.myBackgrounColor = "blue"; }
      //鼠标滑走,背景颜色变回白色
      @HostListener("mouseleave") mouseleave(eventData: Event) { this.myBackgrounColor = "transparent" }
    • 指令的属性绑定 : 动态赋值 <p appBetterHighlight [defaultColor]="'red'" [highlightColor]="'yellow'"> 监听鼠标事件</p>
      import { Directive } from "@angular/core";
      import { OnInit, HostListener, HostBinding, Input } from "@angular/core";
      @Directive({ selector: "[appBetterHighlight]" }) export class BetterHighlightDirective implements OnInit {
      constructor() {}
      @Input() defaultColor = "transparent";
      @Input() highlightColor: string = "blue";

      @HostBinding("style.backgroundColor") myBackgrounColor: string = this .defaultColor;
      ngOnInit(): void { this.myBackgrounColor = this.defaultColor; }
      //鼠标滑过,背景颜色是蓝色
      @HostListener("mouseenter") mouseover(eventData: Event) { this.myBackgrounColor = this.highlightColor; }
      //鼠标滑走,背景颜色变回白色
      @HostListener("mouseleave") mouseleave(eventData: Event) { this.myBackgrounColor = this.defaultColor; } }

      Tips: 这里可以简化写成
      <p [appBetterHighlight]="'yellow'" [defaultColor]="'red'"> 监听鼠标事件</p> @Input('appBetterHighlight') highlightColor: string = "blue";

      html 也可以简化成 <p appBetterHighlight="yellow" defaultColor="red"> 监听鼠标事件</p>

  • 选择指令

    <div [ngSwitch]="value">
    <p *ngSwitchCase="1">value 值是 1</p>
    <p *ngSwitchCase="10">value 值是 10</p>
    <p *ngSwitchCase="100">value 值是 100</p>
    <p *ngSwitchDefault>value 值是默认值</p>
    </div>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Angular Tracy 小笔记 数据绑定,指令 的相关文章