AngularJS 模板语法

作者: Junting | 来源:发表于2018-05-19 20:26 被阅读5次

    模板语法

    模板生成流程图

    模板是编写 Angular 组件最重要的一环,你至少需要深入理解以下知识点才能玩转 Angular 模板:

    1. 对比各种 JS 模板引擎的设计思路
    2. Mustache(八字胡)语法, {}
    3. 模板内的局部变量
    4. 属性绑定、事件绑定、双向绑定
    5. 在模板里面使用结构型指令 ngIf、ngFor、ngSwitch
    6. 在模板里面使用属性型指令 NgClass、NgStyle、NgModel
    7. 在模板里面使用管道格式化数据

    对比各种 JS 模板引擎的设计思路

    什么是模板引擎? 是指利用某种模板语言将页面制成模板,再依据业务逻辑将该模板语言翻译成业务数据,从而生成最终展示页面。 简单的讲就是根据静态HTMl元素和业务逻辑处理的数据结合渲染生成浏览器器需要的页面。

    • jQuery -> Handlebars
    • React -> jsx 模板写法
    • Angular -> 与“指令”紧密结合的模板语法 (vue 也是一样)

    各种模板引擎的唯一目标就是提高开发效率、缩短时间成本。综合来说,无论是哪一种前端模板,大家都比较推崇“轻逻辑”( logic-less )的设计思路。

    何为“轻逻辑”? 简而言之,所谓“轻逻辑”就是说,你不能在模板里面编写非常复杂的 JavaScript 表达式。比如,Angular 的模板语法就有规定:

    • 你不能在模板里面 new 对象
    • 不能使用=、+=、-=这类的表达式
    • 不能用++、--运算符
    • 不能使用位运算符

    为什么要“轻逻辑”?

    1. 本身的 Html 是不识别 if 、for 等操作的;模板引擎处于的地位就是帮忙编译转换纯HTMl元素。
    2. 在 HTML 加入复杂的逻辑,会加大模板引擎编译的时间和计算能力;而且也不建议复杂逻辑处理放到HTMl里来做,保证 HTML 的单一纯洁性;使用模板也是来做简单的插值相关的操作
    3. JS 版的编译器需要在浏览器里面运行,搞得太复杂浏览器拖不动!
    4. 最根本还是模板引擎不够强, 并不是万能的;

    对于 Angular 来说,强调“轻逻辑”还有另一个原因:在组件的整个生命周期里面,模板函数会被执行很多次。你可以想象, Angular 每次要刷新组件的外观的时候,都需要去调用一下模板函数,如果你在模板里面编写了非常复杂的代码,一定会增加渲染时间,用户一定会感到界面有“卡顿”。

    人眼的视觉延迟大约是100ms到400ms之间,如果整个页面的渲染时间超过400ms,界面基本上就卡得没法用了。有一些做游戏的开发者会追求60fps刷新率的细腻感觉,60分之1秒约等于16.7ms,如果 UI 整体的渲染时间超过了16.7ms,就没法达到这个要求了。

    轻逻辑( logic-less )带来了效率的提升,也带来了一些不方便,比如很多模板引擎都实现了 if 语句,但是没有实现 else,所以开发者们在编写复杂业务逻辑的时候模板代码会显得非常啰嗦。

    目前来说,并没有完美的方案能同时兼顾运行效率和语法表现能力,这里只能取一个平衡。

    Mustache 语法

    Mustache 语法也就是你们说的双花括号语法{{...}}。

    关于 Mustache 语法,你需要掌握3点:

    1. 它可以获取到组件里面定义的属性值。
    2. 它可以自动计算简单的数学表达式,例如:加减乘除、取模
    3. 它可以获得方法的返回值。

    插值语法关键代码实例:

    <h3>
        欢迎来到{{title}}!
    </h3>
    
    public title = 'Mustache 语法';
    

    简单的数学表达式求值:

    <p>1 + 5 = {{ 1 + 5 }}</p>
    

    调用组件里面定义的方法:

    <p> {{ getStr() }} </p>
    
    public getStr(): string {
        return '调用方法!'
    }
    

    属性绑定([属性名])

    属性绑定是用方括号来做的,写法:

    <img [src]="imgSrc" />
    <button [disabled]="isUnchanged">是否禁用</button>
    
    public imgSrc:string = './images.png';
    public isUnchanged:boolean = true;
    

    很明显,这种绑定是单向数据绑定,单一的读取值而已。

    事件绑定 ( (事件名) )

    事件绑定是用圆括号来做的,写法:

    <button (click)="btnClick($event)">点击事件</button>
    
    pubic btnClick(e):void {
        alert('点击事件测试~');
    }
    

    双向绑定 ( [(...)] )

    你经常需要显示数据属性,并在用户作出更改时更新该属性。

    在元素层面上,既要设置元素属性,又要监听元素事件变化。

    双向绑定是通过方括号里面套一个圆括号 [(...)] 来做的,模板写法:

    <app-sizer [(size)]="fontSizePx"></app-sizer>
    
    public fontSizePx:number = 14;
    

    模板内的局部变量

    在模板里面使用结构型指令

    Angular 有3个内置的结构型指令:*ngIf*ngForngSwitchngSwitch 的语法比较啰嗦,使用频率小一些, 了解就好。

    *ngIf 代码实例:

    <p *ngIf="isShow">显示还是不显示?</p>
    <button (click)="toggleShow()">控制显示隐藏</button>
    
    public isShow:boolean=true;
    
    public toggleShow():void {
        this.isShow = !this.isShow;
    }
    

    *ngFor 代码实例:

    <ul>
        <li *ngFor="let item of items; let i = index;">
            {{i+1}} - {{ item.name }}
        </li>
    </ul>
    
    public items:Array<any>=[
        {name:"PyCoder"},
        {name:"Jun ting"},
        {name:"EcmaScript"}
    ];
    

    *ngSwitch 代码实例:

    <div [ngSwitch]="mapStatus">
        <p *ngSwitchCase="0">下载中...</p>
        <p *ngSwitchCase="1">正在读取...</p>
        <p *ngSwitchDefault>系统繁忙...</p>
    </div>
    
    public mapStatus:number = 1;
    

    特别注意:一个 HTML 标签上只能同时使用一个结构型的指令。

    因为“结构型”指令会修改 DOM 结构,如果在一个标签上使用多个结构型指令,大家都一起去修改 DOM 结构,到时候到底谁说了算?

    那么需要在同一个 HTML 上使用多个结构型指令应该怎么办呢?有两个办法:

    • 加一层空的 div 标签进行包裹
    • 加一层 <ng-container>

    在模板里面使用属性型指令

    使用频率比较高的3个内置指令是:NgClassNgStyleNgModel

    NgClass 使用案例代码:

    <div [ngClass]="currentClasses">同时批量设置多个样式</div>
    <button (click)="setCurrentClasses()">设置</button>
    
    public currentClasses: [];
    
    public canSave: boolean = true;
    public isUnchanged: boolean = true;
    public isSpecial: boolean = true;
    
    public setCurrentClasses ():void {
        this.currentClasses = {
            'saveable': this.canSave,
            'modified': this.isUnchanged,
            'special': this.isSpecial
        }
    }
    

    相关文章

      网友评论

        本文标题:AngularJS 模板语法

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