美文网首页
NG语法 1

NG语法 1

作者: Daeeman | 来源:发表于2020-10-10 16:25 被阅读0次

    一、 显示数据

    ng的模版中,默认用双大括号{{}}绑定组件中的变量显示出来

    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
        <h1>{{title}}</h1>
        <h2>My favorite hero is: {{myHero}}</h2>
        `,
      styles: [`h1 { color: red }`]
    })
    export class AppComponent {
      title = 'Tour of Heroes';
      myHero = 'Windstorm';
    }
    

    模板来源

    ng的模版和样式可以是内联(上述示例),也可以是单独的文件

    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.scss']
    })
    export class AppComponent {
      title = 'Tour of Heroes';
      myHero = 'Windstorm';
    }
    

    二、模板语法

    1. 模板中的 HTML

    大部分html标签都能在模版中使用,但有一些是毫无意义的:
    html body script base


    2. 插值 {{...}} 和模板表达式

    a. 绑定变量
    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
        <h1>{{title}}</h1>
        <h2>My favorite hero is: {{myHero}}</h2>
        `,
      styles: [`h1 { color: red }`]
    })
    export class AppComponent {
      title = 'Tour of Heroes';
      myHero = 'Windstorm';
    }
    

    b. 绑定方法

    模版中除了绑定变量,还能绑定方法

    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
          <div>Value: {{ getVal() }}/div>
      `,
    })
    export class AppComponent {
      getVal(): number {
        return 33;
      }
    }
    

    c. 模板表达式

    模版中还可以写些简单的逻辑,比如判断或运算

    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
          <p>The sum of 1 + 1 is {{1 + 1}}.</p>
          <p>price的7折 {{price * 0.7}}.</p>
          <p>与方法结合 {{price * 0.7 + getVal()}}.</p>
      `,
    })
    export class AppComponent {
      price = 30
      getVal(): number {
        return 33;
      }
    }
    

    当使用模板表达式时,请遵循下列指南:

    • 非常简单
    • 执行迅速
    • 没有可见的副作用(即模版中的逻辑不能改变组件的变量)

    3、绑定语法

    a. 绑定属性

    绑定图片
    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
        <img src="../assets/images/madao.jpg" alt="madao" />
        <img [src]="madaoSrc" alt="madao" />
        <img bind-src="madaoSrc" alt="madao" />
        `,
      styles: []
    })
    export class AppComponent {
      madaoSrc = '../assets/images/madao.jpg';
    }
    
    绑定普通属性
    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
        <img [src]="user.pic" [alt]="user.name" />
        <table class="table-bordered">
          <tr>
            <th>name</th>
            <th>phone</th>
            <th>age</th>
          </tr>
          <tr>
            <td>张三</td>
            <td>13398490594</td>
            <td>33</td>
          </tr>
          <tr>
            <td [colSpan]="colSpan">李四</td>
            <td>15079049984</td>
            <td>22</td>
          </tr>
        </table>
        <button class="btn btn-primary" [disabled]="isDisabled">click</button>
        `,
      styles: []
    })
    export class AppComponent {
      madaoSrc = '../assets/images/madao.jpg';
      user = {
       name: 'madao',
       pic: this.madaoSrc
      };
      colSpan = 2;
      isDisabled = false;
    }
    
    绑定自定义属性
    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
        <span [attr.data-title]="customTitle">一行文字</span>
        <span [attr.title]="customTitle">test title</span>
        <span [title]="customTitle">test title</span>
        `,
      styles: []
    })
    export class AppComponent {
      madaoSrc = '../assets/images/madao.jpg';
      customTitle = 'bbb';
    }
    

    使用插值表达式绑定属性

    插值也可以用于属性,但常规做法还是用中括号[],建议整个项目保持风格统一

    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
        <img src="{{ user.pic }}" alt="{{ user.name }}" />
        `,
      styles: []
    })
    export class AppComponent {
      madaoSrc = '../assets/images/madao.jpg';
      user = {
        name: 'madao',
        pic: this.madaoSrc
      };
    }
    
    
    <img [src]="' madao'" [alt]="user"/>等价于
    <img src="madao" [alt]="'user' + user2.pic" />
    

    b. 绑定样式class,style

    绑定单个class
    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
          <button type="button" class="btn" [class.btn-primary]="theme === 'primary'">Primary</button>
          <button type="button" class="btn" [class.btn-secondary]="true">secondary</button>
          <button type="button" class="btn" [class.btn-success]="isSuccess">success</button>
          <button type="button" class="btn" [class.btn-danger]="'啦啦啦'">danger</button>
          <button type="button" class="btn" [class.btn-danger]="0">danger</button>
          <button type="button" class="btn" [class.btn-danger]="undefined">danger</button>
        `,
      styles: []
    })
    export class AppComponent {
        theme = 'primary';
        isSuccess = true;
    }
    
    绑定多个class
    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
          <button type="button" [class]="btnCls">btnCls</button>
          <button type="button" [class]="btnCls2">btnCls2</button>
          <button type="button" [class]="btnCls3">btnCls3</button>
    
          <!-- 也可以用内置指令ngClass -->
          <button type="button" [ngClass]="btnCls">btnCls</button>
          <button type="button" [ngClass]="btnCls2">btnCls2</button>
          <button type="button" [ngClass]="btnCls3">btnCls3</button>
        `,
      styles: []
    })
    export class AppComponent {
        btnCls = 'btn btn-primary';
        btnCls2 = ['btn', 'btn-success'];
        btnCls3 = {
          btn: true,
          'btn-info': true
        };
    }
    
    绑定单个style
    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
          <p [style.color]="'#f60'">一段文字</p>
          <p [style.height]="'50px'" [style.border]="'1px solid'">设置高度</p>
          <p [style.height.px]="50" [style.border]="'1px solid'">设置高度</p>
        `,
      styles: []
    })
    export class AppComponent {}
    
    绑定多个style
    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
          <p [style]="style1">style1</p>
          <p [style]="style2">style2</p>
          <p [style]="style3">style3</p>
          <!-- 也可以用内置指令ngStyle, 但不推荐,以后可能会弃用 -->
          <!--  <p [ngStyle]="style1">style1</p>-->
          <!--  <p [ngStyle]="style2">style2</p>-->
    
          <!-- ngStyle只接收对象 -->
          <p [ngStyle]="style3">style3</p>
        `,
      styles: []
    })
    export class AppComponent {
      style1 = 'width: 200px;height: 50px;text-align: center;border: 1px solid;';
      style2 = ['width', '200px', 'height', '50px', 'text-align', 'center', 'border', '1px solid']; // 有问题
      style3 = {
        width: '200px',
        height: '50px',
        'text-align': 'center',
        border: '1px solid'
      };
    }
    

    样式优先级

    • 某个类或样式绑定越具体,它的优先级就越高
    • 绑定总是优先于静态属性

    c. 绑定事件

    基本用法
    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
          <button type="button" class="btn btn-primary" (click)="onClick()">Primary</button>
        `,
      styles: []
    })
    export class AppComponent {
        onClick() {
          console.log('onClick');
        } 
    }
    
    事件对象

    $event就是原生的事件对象

    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
          <button type="button" class="btn btn-primary" (click)="onClick($event)">Primary</button>
        `,
      styles: []
    })
    export class AppComponent {
        onClick(event: MouseEvent) {
          console.log('onClick', event.target);
        }
    }
    

    阻止事件冒泡

    <div (click)="clickParent($event)" class="wrap" style="width: 200px;background-color: #0c5460;">
      <div (click) = "clickChild($event)" class="child" style="width: 100px;height: 200px;background-color: #ff8f77;"></div>
      <!-- <div (click) = "clickChild($event.stopPropagation())" class="child" style="width: 100px;height: 200px;background-color: #ff8f77;"></div> -->
    </div>
    
    clickParent(event: MouseEvent){
      event.stopPropsgation();
      console.log("parent")
    }
    
    clickChild(event: MouseEvent){
      event.stopPropsgation();
      console.log("child")
    }
    

    不是所有元素 event.target都有value

    <input type="text" (keyup)="onKeyup($event)">
    
    onKeyup(event:KeyboardEvent){
        console.log("onInput:",(event.target as HTMLInputElement).value);
      }
    
    <!-- onInput(event:keyboardEvent) {
      console.log('onInput',event.target.value);
    } -->
    

    4 .输入输出(@Input和Output)

    输入属性

    子组件中:

    import { Component, Input } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `<p>
                   Today's item: {{item}}
                 </p>`
    })
    export class ItemDetailComponent  {
      @Input() item: string; // decorate the property with @Input()
    }
    

    父组件中:

    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
         <app-item-detail [item]="currentItem"></app-item-detail>
      `,
    })
    export class AppComponent {
      currentItem = 'Television';
    }
    

    输出属性

    子组件中:

    import { Component, Output, EventEmitter } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `<label>Add an item: <input #newItem></label>
                 <button (click)="addNewItem(newItem.value)">Add to parent's list</button>`,
    })
    export class ItemOutputComponent {
      @Output() newItemEvent = new EventEmitter<string>();
      addNewItem(value: string) {
        this.newItemEvent.emit(value);
      }
    }
    

    父组件中:

    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
         <app-item-output (newItemEvent)="addItem($event)"></app-item-output>
      `,
    })
    export class AppComponent {
       items = ['item1', 'item2', 'item3', 'item4'];
        addItem(newItem: string) {
          this.items.push(newItem);
        }
    }
    

    在元数据中声明输入和输出属性

    固然可以在 @Directive 和 @Component 元数据中声明 inputs 和 outputs,但不推荐示例请看视频演示

    提供别名

    @Input()和@Output()可以接收一个参数,作为变量的别名,那么父组件中只能用别名绑定

    子组件中:

    import { Component, Input, EventEmitter, Output } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `<p>
                   Today's item: {{item}}
                 </p>`
    })
    export class ItemDetailComponent  {
      @Input('aliasItem') item: string; // decorate the property with @Input()
      @Output('newItem') newItemEvent = new EventEmitter<string>();
      addNewItem(value: string) {
         this.newItemEvent.emit(value);
       }
    }
    

    父组件中:

    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
         <app-item-detail [aliasItem]="currentItem" (newItem)="addItem($event)"></app-item-detail>
      `,
    })
    export class AppComponent {
      currentItem = 'Television';
      items = ['item1', 'item2', 'item3', 'item4'];
      addItem(newItem: string) {
        this.items.push(newItem);
      }
    }
    

    输入属性一定要用中括号[]绑定?

    如果绑定的值是静态的,就不需要[]

    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
         <app-item-detail item="static item"></app-item-detail>
      `,
    })
    export class AppComponent {
      // currentItem = 'Television';
    }
    

    5.基本双向绑定

    子组件中:

    import {Component, OnInit, ChangeDetectionStrategy, EventEmitter, Input, Output} from '@angular/core';
    @Component({
      selector: 'app-sizer',
      template: `
        <div>
          <button class="btn btn-danger" (click)="dec()" title="smaller">-</button>
          <button class="btn btn-primary" (click)="inc()" title="bigger">+</button>
          <label [style.font-size.px]="size">FontSize: {{size}}px</label>
        </div>
      `,
      styles: [
      ],
      changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class SizerComponent implements OnInit {
      @Input()  size: number | string;
      
      // 想要用双向绑定语法,output变量名就一定是输入属性名加上Change
      @Output() sizeChange = new EventEmitter<number>();
      constructor() { }
    
      ngOnInit(): void {
      }
      dec() { this.resize(-1); }
      inc() { this.resize(+1); }
    
      resize(delta: number) {
        this.size = Math.min(40, Math.max(8, +this.size + delta));
        this.sizeChange.emit(this.size);
      }
    }
    

    父组件中:

    import { Component } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
         <app-sizer [(size)]="fontSizePx"></app-sizer>
         <div [style.font-size.px]="fontSizePx">Resizable Text</div>
      `,
    })
    export class AppComponent {}
    

    6. 表单双向绑定

    基本使用

    根据之前基本的双向绑定知识,[(ngModel)]语法可拆解为:

    1. 名为ngModel的输入属性
    2. 名为ngModelChange的输出属性
    import {Component} from '@angular/core';
    
    @Component({
      selector: 'example-app',
      template: `
        <input [(ngModel)]="name" #ctrl="ngModel" required>
    
        <p>Value: {{ name }}</p>
        <p>Valid: {{ ctrl.valid }}</p>
    
        <button (click)="setValue()">Set value</button>
      `,
    })
    export class SimpleNgModelComp {
      name: string = '';
    
      setValue() {
        this.name = 'Nancy';
      }
    }
    

    <input [(ngModel)]="name" />上面这行代码相当于: <input [value]="name" (input)="name = $event.target.value" />

    在表单中使用

    表单中使用[(ngModel)],需要做下面两件事的其中之一:

    • 给控件加上name属性
    • 将ngModelOptions.standalone设为true
    <form>
      <form>
        <input [(ngModel)]="value" name="name" />
        <input [(ngModel)]="value" [ngModelOptions]="{ standalone: true }" />
      </form>
    </form>
    

    7 *ngIf

    基本使用

    ngIf是内置的结构型指令,控制宿主元素的添加或删除,取决于绑定的值是否为真

    import {Component} from '@angular/core';
    @Component({
      selector: 'app-if',
      template: `
        <div *ngIf="condition">Content to render when condition is true.</div>
      `,
    })
    export class IfComp {
      condition = true;
    }
    

    扩展写法

    *ngIf是个语法糖,上个例子完整的写法如下

    import {Component} from '@angular/core';
    @Component({
      selector: 'app-if',
      template: `
        <ng-template [ngIf]="condition">
          <div>Content to render when condition is true.</div>
        </ng-template>
      `,
    })
    export class IfComp {
      condition = true;
    }
    

    ng-template是一块内嵌模板,类型是TemplateRef,下文和后面的课程会讲到

    ngIfElese

    import {Component} from '@angular/core';
    @Component({
      selector: 'app-if',
      template: `
        <button class="btn btn-primary" (click)="condition = !condition">toggle show</button>
        <div *ngIf="condition; else elseBlock">condition为真时显示</div>
        <ng-template #elseBlock>
          <p>condition为假时显示</p>
        </ng-template>
      `,
    })
    export class IfComp {
      condition = true;
    }
    

    ngIfElese(拓展写法)

    import {Component} from '@angular/core';
    @Component({
      selector: 'app-if',
      template: `
        <button class="btn btn-primary" (click)="condition = !condition">toggle show</button>
        <div *ngIf="condition; else elseBlock">condition为真时显示</div>
        <ng-template #elseBlock>
          <p>condition为假时显示</p>
        </ng-template>
      `,
    })
    export class IfComp {
      condition = true;
    }
    

    上面例子中的elseBlock并非组件中的某变量,而是TemplateRef的引用

    ngIfThen

    import {Component} from '@angular/core';
    @Component({
      selector: 'app-if',
      template: `
        <div *ngIf="condition; then thenBlock else elseBlock"></div>
        <ng-template #thenBlock>condition为true时显示</ng-template>
        <ng-template #elseBlock>condition为false时显示</ng-template>
      `,
    })
    export class IfComp {
      condition = true;
    }
    

    上面这种写法和ngIfElese实例一样,所以没必要这么写

    使用TemplateRef

    上面示例中的else 或 then 后面跟的变量都是模板的引用而非组件中的变量,下面演示怎么用组件中的变量

    import {Component, OnInit, ChangeDetectionStrategy, ViewChild, TemplateRef, AfterViewInit} from '@angular/core';
    @Component({
      selector: 'app-if',
      template: `
        <button class="btn btn-primary" (click)="condition = !condition">toggle block</button>
        <p *ngIf="condition else elseBlocks">{{ condition }} === true 时显示</p>
        <ng-template #firstTpl>
          <p>{{ condition }} === false 时显示</p>
        </ng-template>
      `,
    })
    export class IfComponent implements OnInit, AfterViewInit {
      elseBlocks: TemplateRef<any> = null;
      @ViewChild('firstTpl', {static: true}) primaryBlock: TemplateRef<any> = null;
      condition = false;
      constructor() {
    
      }
      ngOnInit(): void {
        console.log('ngOnInit', this.primaryBlock);
        this.elseBlocks = this.primaryBlock;
      }
    }
    

    8 *ngSwitch

    基本使用
    ngSwitch是内置的结构型指令,控制显示那个模版,类似js中的switch

    import {Component} from '@angular/core';
    @Component({
      selector: 'app-switch',
      template: `
        <p>
          <input type="radio" name="fruit" value="apple" id="apple" [(ngModel)]="fruit" />
          <label for="apple">🍎</label>
        </p>
        <p>
          <input type="radio" name="fruit" value="pear" id="pear" [(ngModel)]="fruit" />
          <label for="pear">🍐</label>
        </p>
        <p>
          <input type="radio" name="fruit" value="grape" id="grape" [(ngModel)]="fruit" />
          <label for="grape">🍇</label>
        </p>
        <p>
          <input type="radio" name="fruit" value="other" id="other" [(ngModel)]="fruit" />
          <label for="other">other</label>
        </p>
        
        selected fruit: {{ fruit }}
        
        <div class="content" [ngSwitch]="fruit">
          <p *ngSwitchCase="'apple'">这是 苹果</p>
          <p *ngSwitchCase="'pear'">这是 梨</p>
          <p *ngSwitchCase="'grape'">这是 葡萄</p>
          <p *ngSwitchDefault>啥都不是</p>
        </div>
      `,
    })
    export class SwitchComponent {
      fruit = '';
    }
    

    9 *ngFor

    基本使用

    import {Component} from '@angular/core';
    const Heros = [
      {
        id: 'hero_0',
        name: '盖伦'
      },
      {
        id: 'hero_1',
        name: '赵信'
      },
      {
        id: 'hero_2',
        name: '嘉文'
      },
      {
        id: 'hero_3',
        name: '易大师'
      },
      {
        id: 'hero_3',
        name: '泰达米尔'
      }
    ];
    interface Hero {
      id: string;
      name: string;
    }
    
    @Component({
      selector: 'app-switch',
      template: `
        <ul>
          <li *ngFor="let item of heros" [style.color]="item.id === 'hero_2' ? 'orange' : '#333'">{{ item.id }}</li>
        </ul>
      `,
    })
    export class SwitchComponent {
      heros: Hero[] = Heros;
    }
    

    trackBy

    trackBy接收一个函数,返回 NgFor 应该跟踪的值(比如id),这样刷新列表时,id相同的dom不会触发更新

    import {Component} from '@angular/core';
    @Component({
      selector: 'app-switch',
      template: `
        <p>
          add hero:
          <button class="btn btn-info" (click)="reset()">reset</button>
        </p>
        <ul>
          <li *ngFor="let item of heros; trackBy: trackByHero" [style.color]="item.id === 'hero_2' ? 'orange' : '#333'">{{ item.id }}</li>
        </ul>
      `,
    })
    export class SwitchComponent {
      heros: Hero[] = Heros;
      reset() {
        this.heros = [
          {
            id: 'hero_4',
            name: '盖伦4'
          },
          {
            id: 'hero_5',
            name: '赵信5'
          },
          {
            id: 'hero_2',
            name: '嘉文'
          },
          {
            id: 'hero_6',
            name: '易大师6'
          },
          {
            id: 'hero_7',
            name: '泰达米尔7'
          }
        ];
      }
      trackByHero(hero: Hero): string {
        return hero.id;
      }
    }
    

    局部变量

    • $implicit: T:迭代目标(绑定到ngForOf)中每个条目的值。
    • ngForOf: NgIterable:迭代表达式的值。当表达式不局限于访问某个属性时,这会非常有用,比如在使用 async 管道时(userStreams | async)。
    • index: number:可迭代对象中当前条目的索引。
    • count: number:可迭代对象的长度。
    • first: boolean:如果当前条目是可迭代对象中的第一个条目则为 true。
    • last: boolean:如果当前条目是可迭代对象中的最后一个条目则为 true。
    • even: boolean:如果当前条目在可迭代对象中的索引号为偶数则为 true。
    • odd: boolean:如果当前条目在可迭代对象中的索引号为奇数则为 true。
    import {Component} from '@angular/core';
    @Component({
      selector: 'app-switch',
      template: `
        <ul>
          <li
            *ngFor="let item of heros; index as i count as len; let ev = even; let od = odd; let f = first; let l = last trackBy: trackByHero"
          [class.even]="ev"
          [class.odd]="od">
            <p>first: {{ f }} -- last: {{ l }}</p>
            <p>name: {{ item.name }}</p>
            <p>length: {{ len }}</p>
            <p>index: {{ i }}</p>
            <hr />
          </li>
        </ul>
      `,
        styles: [`
        .even {
          color: #82fa54;
        }
    
        .odd {
          color: #698efa;
        }
      `]
    })
    export class SwitchComponent {
      heros: Hero[] = Heros;
      trackByHero(hero: Hero): string {
        return hero.id;
      }
    }
    

    10 模板引用变量

    基本使用

    使用井号(#)声明模板引用变量,可以获取DOM 元素、指令、组件、TemplateRef 或 Web Component。

    之前用到的ng-template上的 # ,就是模板引用变量,并在组件中获取到了对应的TemplateRef

    import {Component} from '@angular/core';
    @Component({
      selector: 'app-tpl-var',
      template: `
        <input #phone placeholder="phone number" />
        <button (click)="callPhone(phone.value)">Call</button>
      `,
    })
    export class TplVarComponent {
      constructor() { }
      callPhone(value: string) {
        console.log('callPhone', value);
      }
    }
    

    ref

    还有种写法就是ref, 下面两种写法是一样的

    <input #fax placeholder="fax number" />
    <br />
    <input ref-fax placeholder="fax number" />
    
    

    引用组件

    import {Component} from '@angular/core';
    @Component({
      selector: 'app-tpl-var',
      template: `
        <div class="demo-sec">
          <button class="btn btn-primary" (click)="sizer.inc()">app inc</button>
          <app-sizer [(size)]="size" #sizer></app-sizer>
          size: {{ size }}
        </div>
      `,
    })
    export class TplVarComponent {
      size = 16;
      constructor() { }
    }
    

    11 模板运算符

    管道(|)

    管道可以理解为把模板上的值丢进一条或多条管道,经过管道的处理输出一条新的值

    import {Component} from '@angular/core';
    @Component({
      selector: 'app-tpl-var',
      template: `
        <p>Title through uppercase pipe: {{title | uppercase}}</p>
        <p>Title through uppercase pipe: {{title | uppercase | lowercase}}</p>
        <p>json: {{ obj | json }}</p>
      `,
    })
    export class TplOperatorsComponent {
      title = 'aBc';
      obj = {
          name: 'aaa',
          time: '1980-02-25T05:00:00.000Z',
          price: '$333'
        };
      constructor() {}
    }
    

    带参数的管道

    如内置的date管道

    import {Component} from '@angular/core';
    @Component({
      selector: 'app-tpl-var',
      template: `
        <p>Manufacture date with date format pipe: {{now | date:'longDate'}}</p>
        <p>Manufacture date with date format pipe: {{now | date:'yyyy-MM-dd'}}</p>
      `,
    })
    export class TplOperatorsComponent {
      now = Date.now();
      constructor() {}
    }
    

    所有内置管道

    安全导航运算符(?)

    安全导航运算符是 es2020 中的新语法,又叫可选链

    import {Component} from '@angular/core';
    @Component({
      selector: 'app-tpl-var',
      template: `
        <!--<p *ngIf="hero">hero: {{ hero.name }}</p>-->
        <p>hero: {{ hero?.name }}</p>
      `,
    })
    export class TplOperatorsComponent {
       hero: Hero;
        constructor() {
          setTimeout(() => {
            this.hero = {
              id: 'hero_00',
              name: '龙龟'
            };
          }, 2000);
        }
    }
    

    非空断言(!)

    在ts中,开启--strictNullChecks后,将一个可能是undefined或null的变量赋给一个有确切类型的变量时,会报错

    但在特定情况下,我们很确定那个变量一定不是undefined或null,这个时候就可以用非空断言操作符
    用了这个操作符的变量,可以理解为叫ts不要去操心了,我这个变量一定是有值的 非空断言生效的前提是开启 --strictNullChecks

    使用非空断言的两个步骤:

    • tsconfig.json中设置"strictNullChecks": true,
    • tslint.json中设置 "no-non-null-assertion": false
    import {Component} from '@angular/core';
    @Component({
      selector: 'app-tpl-var',
      template: `
        <input #phone placeholder="phone number" />
        <button (click)="callPhone(phone.value)">Call</button>
      `,
    })
    export class TplOperatorsComponent {
      name: string | null = '';
      constructor() {
        // 报错,this.name可能为null, 不能赋给heroName
        const heroName: string = this.name;
    
        // 不报错,告诉ts,this.name一定不是null
        const heroName: string = this.name!;
    
        // 以上写法相当于
        if (this.name) {
          const heroName: string = this.name;
        }
      }
    }
    

    类型转换函数 $any()

    有时候,绑定的表达式不能或很难指定类型。要消除这种报错,你可以使用 any() 转换函数来把表达式转换成 any 类型 假设无法确定item的类型,也就不能确定item是否有bestByDate,这时就会报错,可以用any()把item视为any类型,避免其报错

    <p>The item's undeclared best by date is: {{$any(item).bestByDate}}</p>
    
    

    也可以用这个函数绑定组件中不存在的变量

    <p>The item's undeclared best by date is: {{$any(this).bestByDate}}</p>
    

    相关文章

      网友评论

          本文标题:NG语法 1

          本文链接:https://www.haomeiwen.com/subject/zpbsuktx.html