Angular2文档学习的知识点摘要——显示数据、用户输入、表单

目录

显示数据

  在 Angular 中最典型的数据显示方式,就是把 HTML 模板中的控件绑定到 Angular 组件的属性。

使用插值表达式显示组件属性

  1. 要显示组件的属性,最简单的方式就是通过插值表达式 (interpolation) 来绑定属性名。 要使用插值表达式,就把属性名包裹在双花括号里放进视图模板,如{{myHero}}。
  2. 模板是包在 ECMAScript 2015 反引号 () 中的一个多行字符串。 反引号 () — 注意,不是单引号 (‘) — 允许把一个字符串写在多行上, 使 HTML 模板更容易阅读。

用户输入

  用户输入触发 DOM 事件。我们通过事件绑定来监听它们,把更新过的数据导入回我们的组件和 model。
1. 要绑定 DOM 事件,只要把 DOM 事件的名字包裹在圆括号中,然后用放在引号中的模板语句对它赋值就可以了。
2. 写绑定时,需要知道模板语句的执行上下文。 出现在模板语句中的每个标识符都属于特定的上下文对象。 这个对象通常都是控制此模板的 Angular 组件。
3. DOM 事件可以携带可能对组件有用的信息。如:通过 event4. event对象的属性取决于 DOM 事件的类型。
5. 当用户按下并释放一个按键时,触发keyup事件,Angular 在$event变量提供一个相应的 DOM 事件对象。在组件中使用event.target.value可获取输入的值。
6. 所有标准 DOM 事件对象都有一个target属性, 引用触发该事件的元素。


模板引用变量

  还有另一种获取用户数据的方式:使用 Angular 的模板引用变量。 这些变量提供了从模块中直接访问元素的能力。 在标识符前加上井号 (#) 就能声明一个模板引用变量。

@Component({
  selector: 'key-up2',
  template: `
    <input #box (keyup)="onKey(box.value)">
    <p>{{values}}</p>
  `
})
export class KeyUpComponent_v2 {
  values = '';
  onKey(value: string) {
    this.values += value + ' | ';
  }
}

按键事件过滤

  1. (keyup)事件处理器监听每一次按键。 有时只在意回车键,因为它标志着用户结束输入。 解决这个问题的一种方法是检查每个$event.keyCode,只有键值是回车键时才采取行动。
  2. 更简单的方法是:绑定到 Angular 的keyup.enter 模拟事件。 然后,只有当用户敲回车键时,Angular 才会调用事件处理器。

表单

模板驱动的表单

  1. 如果组件、指令或管道出现在模块的imports数组中,不要把它声明在declarations数组中。 如果它是你自己写的,并且属于当前模块,就要把它声明在declarations数组中。
  2. 当在表单中使用[(ngModel)]时,必须要定义name属性。
  3. 在内部,Angular 创建了一些FormControl,并把它们注册到NgForm指令,再将该指令附加到标签。 注册每个FormControl时,使用name属性值作为键值。
  4. 每个 input 元素都有name属性,Angular 表单用它注册控件。
  5. 在属性绑定中,值从模型中流动到屏幕上的目标属性 (property)。 通过把属性名括在方括号中来标记出目标属性,[]。 这是从模型到视图的单向数据绑定。
  6. 在事件绑定中,值从屏幕上的目标属性流动到模型。 通过把属性名括在圆括号中来标记出目标属性,()。 这是从视图到模型的反向单向数据绑定。
  7. Angular 选择了组合标点 [()] 来标记出双向数据绑定和双向数据流
  8. 事实上,可以把NgModel绑定拆成两个独立的绑定,如:<input type="text" class="form-control" id="name" required [ngModel]="model.name" name="name" (ngModelChange)="model.name = $event" >
      其中:ngModelChange并不是元素的事件。 它实际上是来自NgModel指令的事件属性。
  9. 当 Angular 在表单中看到[(x)]的绑定目标时, 它会期待这个x指令有一个名为x的输入属性,和一个名为xChange的输出属性。
  10. 模板表达式中的另一个古怪之处是model.name = $event。 之前看到的$event对象来自 DOM 事件。 但ngModelChange属性不会生成 DOM 事件 —— 它是Angular EventEmitter类型的属性,当它触发时, 它返回的是输入框的值 —— 也正是希望赋给模型name属性的值。
  11. 在表单中使用ngModel可以获得比仅使用双向数据绑定更多的控制权。它还会告诉我们很多信息:用户碰过此控件吗?它的值变化了吗?数据变得无效了吗?
  12. NgModel 指令不仅仅跟踪状态。它还使用特定的 Angular CSS 类来更新控件,以反映当前状态。 可以利用这些 CSS 类来修改控件的外观,显示或隐藏消息。
状态为真时的CSS类为假时的CSS类
控件已经被访问过ng-touchedng-untouched
控件值已经变化ng-dirtyng-pristine
控件值是有效的ng-validng-invalid

 13. 在控件上加入模板引用变量,通过模板引用变量.className可以查看当前控件所拥有的类。
 14. 模板引用变量可以访问模板中输入框的 Angular 控件。如:

<input type="text" required [(ngModel)]="model.name" name="name" #name="ngModel">

  这里,创建了名为name的变量,并且赋值为“ngModel”。
  注:为什么是“ngModel”?指令exportAs属性告诉Angular如何链接模板引用变量到指令。这里把name设置为ngModel是因为ngModel指令的exportAs属性设置成了“ngModel”。
 15. 在form表单上添加模板引用变量,并且赋值为ngForm,如:#heroForm="ngForm",现在heroForm变量引用的是NgForm指令,它代表的是表单的整体。可以在Angular表达式中使用该模板引用变量的reset方法,重置表单的状态。如:

<button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button>

.
 16. 什么NgForm指令?之前没有添加过 NgForm 指令啊!是 Angular 干的。Angular 自动创建了NgForm指令,并把它附加到标签。
17. NgForm指令为form元素扩充了额外的特性。它持有通过ngModel指令和name属性为各个元素创建的那些控件,并且监视它们的属性变化,包括有效性。它还有自己的valid属性,只有当其中所有控件都有效时,它才有效。
18. 如可以通过heroForm变量(上述中提到的模板变量heroForm)把按钮的disabled属性绑定到表单的整体有效性。

<button type="submit" [disabled]="!heroForm.form.valid">Submit</button>

案例angular-forms

模型类 hero.ts

export class Hero {
    constructor(public id: number, public name: string, public power: string, public alterEgo?: string) {

    }
}

组件 hero-form.component.ts

import { Component } from '@angular/core';
import { Hero } from './hero';

@Component({
    moduleId: module.id,
    selector: 'hero-form',
    templateUrl: 'hero-form.component.html'
})
export class HeroFormComponent {
    powers = [
        'Really smart', 'Super Flexible',
        'Super Hot', 'Weather Changer'
    ];

    model = new Hero(18, 'Dr IQ', this.powers[0], 'Chuck Overstreet');

    submitted = false;

    onSubmit() {
        this.submitted = true;
    }

    // TODO: Remove this when we're done
    get diagnostic() {
        return JSON.stringify(this.model);
    }

    newHero() {
        this.model = new Hero(42, '', '');
    }
}

hero-form.component.html

<div class="container">
    <div [hidden]="submitted">
        <h1>Hero Form</h1>
        <form (ngSubmit)="onSubmit()" #heroForm="ngForm"> <!--{{diagnostic}}-->
            <div class="form-group">
                <label for="name">Name</label>
                <input type="text" class="form-control" id="name" required [(ngModel)]="model.name" name="name" #name="ngModel"> </div>
            <div [hidden]="name.valid || name.pristine" class="alert alert-danger"> Name is required </div>
            <div class="form-group">
                <label for="alterEgo">Alter Ego</label>
                <input type="text" class="form-control" id="alterEgo" [(ngModel)]="model.alterEgo" name="alterEgo"> </div>
            <div class="form-group">
                <label for="power">Hero Power</label>
                <select id="power" class="form-control" required [(ngModel)]="model.power" name="power">
                    <option *ngFor="let pow of powers" [value]="pow">{{pow}}</option>
                </select>
            </div>
            <button type="submit" class="btn btn-default" [disabled]="!heroForm.form.valid">Submit</button>
        </form>
        <br/>
        <button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button>
    </div>
    <div [hidden]="!submitted">
        <h2>You submitted the following:</h2>
        <div class="row">
            <div class="col-xs-3">Name</div>
            <div class="col-xs-9  pull-left">{{ model.name }}</div>
        </div>
        <div class="row">
            <div class="col-xs-3">Alter Ego</div>
            <div class="col-xs-9 pull-left">{{ model.alterEgo }}</div>
        </div>
        <div class="row">
            <div class="col-xs-3">Power</div>
            <div class="col-xs-9 pull-left">{{ model.power }}</div>
        </div>
        <br>
        <button class="btn btn-default" (click)="submitted=false">Edit</button>
    </div>
</div>

注:使用到ngModel时,需要在控件上添加name属性。

根模块 app.module.ts

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

import { AppComponent }  from './app.component';
import { HeroFormComponent } from './hero-form.component';

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HeroFormComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

注:因为模板驱动的表单位于它们自己的模块,所以在使用表单之前,需要将FormsModule添加到应用模块的imports数组中。

根组件 app.component.ts

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

@Component({
  selector: 'my-app',
  template: `<hero-form></hero-form>`,
})
export class AppComponent  { }

引导根模块 main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

示例页面 index.html

  在index.html页面的body标签中添加:

<my-app>Loading AppComponent content here ...</my-app>

定制CSS类,提供无效控件的视觉反馈 forms.css

.ng-valid[required], .ng-valid.required {
    border-left: 5px solid #42A948; /* green */
}

.ng-invalid:not(form) {
    border-left: 5px solid #a94442; /* red */
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值