zoukankan      html  css  js  c++  java
  • 组件与模板(二) 模板语法

      Angular 应用管理着用户之所见和所为,并通过 Component 类的实例(组件)和面向用户的模板来与用户交互。

      从使用模型-视图-控制器 (MVC) 或模型-视图-视图模型 (MVVM) 的经验中,很多开发人员都熟悉了组件和模板这两个概念。 在 Angular 中,组件扮演着控制器或视图模型的角色,模板则扮演视图的角色。

      模板绑定是通过 (DOM) property 和事件来工作的,而不是 (HTML) attribute。

      在 Angular 的世界中,attribute 唯一的作用是用来初始化元素和指令的状态。 当进行数据绑定时,只是在与元素和指令的 property 和事件打交道,而 attribute 就完全靠边站了。

    绑定语法:概览

    绑定的类型可以根据数据流的方向分成三类: 从数据源到视图、从视图到数据源以及双向的从视图到数据源再到视图。

    数据方向

    DOM 属性(Property)语法

    绑定类型

    单向
    从数据源
    到视图

    {{expression}}

    [target]="expression"

    bind-target="expression"

    插值表达式
    属性
    Attribute
    CSS 类
    样式

    从视图到数据源的单向绑定

    (target)="statement"

    on-target="statement"

    事件

    双向

    [(target)]="expression"

    bindon-target="expression"

    双向

    绑定目标

    数据绑定的目标是 DOM 中的某些东西。 这个目标可能是(元素 | 组件 | 指令的)property、(元素 | 组件 | 指令的)事件,或(极少数情况下) attribute 名。 下面是的汇总表:

    绑定类型

    目标

    范例

    属性

    元素的 property
    组件的 property
    指令的 property

    //元素属性设置为组件属性的值

    <img [src]="heroImageUrl">

    //设置自定义组件的模型属性(这是父子组件之间通讯的重要途径):

    <app-hero-detail [hero]="currentHero"></app-hero-detail>

    //指令的属性

    <div [ngClass]="{'special': isSpecial}"></div>

    事件

    元素的事件
    组件的事件
    指令的事件

    <button (click)="onSave()">Save</button>

    <app-hero-detail (deleteRequest)="deleteHero()"></app-hero-detail>

    <div (myClick)="clicked=$event" clickable>click me</div>

    双向

    事件与 property

    <input [(ngModel)]="name">

    Attribute

    attribute(例外情况)

    <button [attr.aria-label]="help">help</button>

    CSS 类

    class property

    <div [class.special]="isSpecial">Special</div>

    样式

    style property

    <button [style.color]="isSpecial ? 'red' : 'green'">

    事件名和目标事件

    圆括号中的名称 —— 比如 (click) —— 标记出目标事件。在下面例子中,目标是按钮的 click 事件。

    <button (click)="onSave()">Save</button>

    有些人更喜欢带 on- 前缀的备选形式,称之为规范形式:

    <button on-click="onSave()">On Save</button>

    元素事件可能是更常见的目标,但 Angular 会先看这个名字是否能匹配上已知指令的事件属性,就像下面这个例子:

    <!-- `myClick` is an event on the custom `ClickDirective` -->
    <div (myClick)="clickMessage=$event" clickable>click with myClick</div>

    $event 和事件处理语句

    在事件绑定中,Angular 会为目标事件设置事件处理器。

    当事件发生时,这个处理器会执行模板语句。 典型的模板语句通常涉及到响应事件执行动作的接收器,例如从 HTML 控件中取得值,并存入模型。

    绑定会通过名叫 $event 的事件对象传递关于此事件的信息(包括数据值)。

    事件对象的形态取决于目标事件。如果目标事件是原生 DOM 元素事件, $event 就是 DOM 事件对象,它有像 target 和 target.value 这样的属性。

    考虑这个范例:

    <input [value]="currentHero.name"
           (input)="currentHero.name=$event.target.value" >

    上面的代码在把输入框的 value 属性绑定到 name 属性。 要监听对值的修改,代码绑定到输入框的 input 事件。 当用户造成更改时,input 事件被触发,并在包含了 DOM 事件对象 ($event) 的上下文中执行这条语句。

    要更新 name 属性,就要通过路径 $event.target.value 来获取更改后的值。

    使用 EventEmitter 实现自定义事件

    通常,指令使用 Angular EventEmitter 来触发自定义事件。 指令创建一个 EventEmitter 实例,并且把它作为属性暴露出来。 指令调用 EventEmitter.emit(payload) 来触发事件,可以传入任何东西作为消息载荷。 父指令通过绑定到这个属性来监听事件,并通过 $event 对象来访问载荷。

    假设 HeroDetailComponent 用于显示英雄的信息,并响应用户的动作。 虽然 HeroDetailComponent 包含删除按钮,但它自己并不知道该如何删除这个英雄。 最好的做法是触发事件来报告“删除用户”的请求。

    下面的代码节选自 HeroDetailComponent

    template: `
    <div>
      <img src="{{heroImageUrl}}">
      <span [style.text-decoration]="lineThrough">
        {{prefix}} {{hero?.name}}
      </span>
      <button (click)="delete()">Delete</button>
    </div>`
    // This component makes a request but it can't actually delete a hero.
    deleteRequest = new EventEmitter<Hero>();
    
    delete() {
      this.deleteRequest.emit(this.hero);
    }

    组件定义了 deleteRequest 属性,它是 EventEmitter 实例。 当用户点击删除时,组件会调用 delete() 方法,让 EventEmitter 发出一个 Hero 对象。

    现在,假设有个宿主的父组件,它绑定了 HeroDetailComponent 的 deleteRequest 事件。

    <app-hero-detail (deleteRequest)="deleteHero($event)" [hero]="currentHero"></app-hero-detail>

    当 deleteRequest 事件触发时,Angular 调用父组件的 deleteHero 方法, 在 $event 变量中传入要删除的英雄(来自 HeroDetail)。

    内置指令

    可分为属性型指令 或 结构型指令

    最常用的属性型指令:

    使用[(ngModel)]双向绑定到表单元素

    导入 FormsModule 并让 [(ngModel)] 可用的代码如下:

    import { NgModule } from '@angular/core';
    import { BrowserModule }  from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms'; // JavaScript import from Angular
    
    /* Other imports */
    
    @NgModule({
      imports: [
        BrowserModule,
        FormsModule  // import into the NgModule
      ],
      /* Other module metadata */
    })
    export class AppModule { }

    [(ngModel)]内幕

    回头看看 name 绑定,注意,你可以通过分别绑定到 <input> 元素的 value 属性和 input 事件来达到同样的效果。

    <input [value]="currentHero.name"
           (input)="currentHero.name=$event.target.value" >

    那样显得很笨重,谁会记得该设置哪个元素属性以及当用户修改时触发哪个事件? 你该如何提取输入框中的文本并且更新数据属性?谁会希望每次都去查资料来确定这些?

    ngModel 指令通过自己的输入属性 ngModel 和输出属性 ngModelChange 隐藏了那些细节。

    <input
      [ngModel]="currentHero.name"
      (ngModelChange)="currentHero.name=$event">

    ngModel 输入属性会设置该元素的值,并通过 ngModelChange 的输出属性来监听元素值的变化。

    内置结构型指令

    常见结构型指令的简介:

    • NgIf - 根据条件把一个元素添加到 DOM 中或从 DOM 移除

    • NgSwitch 一组指令,用来在多个可选视图之间切换。

    • NgForOf - 对列表中的每个条目重复套用同一个模板

  • 相关阅读:
    startup毕业论文
    LeetCode OJ
    LeetCode OJ
    LeetCode OJ
    LeetCode OJ
    LeetCode OJ
    install
    逻辑卷(lv)管理(LVM)
    mke2fs
    cat & 文件结束符
  • 原文地址:https://www.cnblogs.com/AndyChen2015/p/9628989.html
Copyright © 2011-2022 走看看