天天看點

Angular4-線上競拍應用-資料綁定

使用插值表達式将一個表達式的值顯示在模闆上

使用方括号将HTML标簽的一個屬性綁定到一個表達式上

使用小括号将元件控制器的一個方法綁定為模闆上一個事件的處理器

預設的綁定是單向的

事件綁定

Angular4-線上競拍應用-資料綁定

如果處理事件的方法需要了解事件的屬性可以給處理事件的方法添加一個$event參數

這個參數的target屬性指向觸發事件的DOM對象,也就是input節點。

等号右邊可以不是一個函數調用,也可以是一個屬性指派。

建立一個項目ng new demo1

建立一個元件ng g component bind

修改bind.component.html

<p>
  bind works!
</p>
<button (click)="doOnClick($event)">點我</button>
           

修改bind.component.ts

export class BindComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

  doOnClick(event:any){
    console.log(event);
  }

}
           

修改app.component.html

啟動程式

DOM屬性程式設計

修改bind.component.html

<p>
  bind works!
</p>
<img [src]="imgUrl">
<img src="{{imgUrl}}">
           

修改bind.component.ts

export class BindComponent implements OnInit {

  imgUrl:string="http://placehold.it/400x220";

  constructor() { }

  ngOnInit() {
  }

}
           

實際上,Angular渲染頁面前會把插值表達式翻譯成屬性綁定

插值表達式和屬性綁定是一個東西。沒有哪個更好一說,但程式設計的時候盡量用一種寫法。

修改bind.component.html

<p>
  bind works!
</p>
<input value="Tom" (input)="doOnInput($event)">
           

修改bind.component.ts

export class BindComponent implements OnInit {

  constructor() { }

  ngOnInit() {}

 doOnInput(event:any){
    console.log(event.target.value);//dom屬性值,會改變
    console.log(event.target.getAttribute('value'));//html屬性,初始值,不會改變
  }

}
           

會發現HTML屬性列印的始終是Tom,而dom屬性會随着輸入内容的改變而改變。

HTML屬性和DOM屬性的關系

  • 少量HTML屬性和DOM屬性之間有着1對1的映射,如id
  • 有些HTML屬性沒有對應的DOM屬性,如colspan
  • 有些DOM屬性沒有對應的HTML屬性,如textContent
  • 就算名字相同,HTML屬性和DOM屬性也不是同一樣東西
  • HTML屬性的值指定了初始值;DOM屬性的值表示目前值
  • DOM屬性的值可以改變;HTML屬性的值不能改變
  • 模闆綁定是通過DOM屬性和事件來工作的,而不是HTML屬性

插值表達式是DOM屬性綁定

Angular4-線上競拍應用-資料綁定

HTML屬性綁定

基本HTML屬性綁定

我們應該優先使用DOM屬性綁定,那麼為什麼還要用HTML屬性綁定呢。當沒有DOM屬性綁定的時候就要用HTML屬性綁定了。

比如td的colspan是純HTML屬性,沒有對應的DOM屬性

修改bind.component.html

<p>
  bind works!
</p>
<table>
  <tr><td colspan="{{1+1}}">慕課網</td> </tr>
</table>
           

通路http://localhost:4200/

檢視控制台,會發現會報一個異常

Uncaught Error: Template parse errors:
Can't bind to 'colspan' since it isn't a known property of 'td'. ("
</p>
<table>
  <tr><td [ERROR ->]colspan="{{1+1}}">慕課網</td> </tr>
</table>
           

因為插值表達式是DOM屬性綁定隻能去設定td的DOM屬性,不能設定其HTML屬性。

在這種情況下隻能使用HTML屬性綁定。

修改bind.component.html

<p>
  bind works!
</p>
<table>
  <tr><td [attr.colspan]="size">慕課網</td> </tr>
</table>
           

在bind.component.ts中添加一個屬性size

再檢視頁面,會發現有内容了。

Angular4-線上競拍應用-資料綁定

CSS屬性綁定

CSS類綁定

<div class="aaa bbb" [class]="someExpression">something</div>
<div [class.special]="isSpecial">something</div>
<div [ngClass]="{{aaa:isA,bbb:isB}}">
           

第一種[class]的樣式會代替前邊class的樣式

第二種,isSpecial是一個布爾值,為true則顯示這個樣式

第三種,可以控制多個class是否顯示,aaa就是class類的名字

樣式綁定

<button [style.color]="isSpecial?'red':'green'">Red</button>
<div [ngStyle]="{'font-style':this.canSave?'italic':'normal'}">
           

CSS類綁定

修改bind.component.css

.a{
  background: yellow;
}

.b{
  color:red;
}

.c{
  font-size:px;
}
           

修改bind.component.html

<p>
  bind works!
</p>
<div class="a b c">慕課網</div>
           

然後檢視頁面。

這是用原始的方式來綁定class類。

修改bind.component.html

<p>
  bind works!
</p>
<div [class]="divClass">慕課網</div>
           

修改bind.component.ts,設定3秒後改變class屬性

divClass:string;

  constructor() {
    setTimeout(()=>{
      this.divClass="a b c"
    },3000)
  }
           

第二種綁定方式,隻改變部分class

修改bind.component.html

<p>
  bind works!
</p>
<div class="a b" [class.c]="isBig">慕課網</div>
           

修改bind.component.ts

isBig:boolean=false;


  constructor() {
    setTimeout(()=>{
      this.isBig=true;
    },3000)
  }
           

同時管理多個類

修改bind.component.html

<p>
  bind works!
</p>
<div [ngClass]="divClass">慕課網</div>
           

修改bind.component.ts

divClass: any = {
    a: false,
    b: false,
    c: false
  }


  constructor() {
    setTimeout(() => {
      this.divClass = {
        a: true,
        b: true,
        c: true
      }
    }, 3000)
  }
           

内聯class的綁定

<p>
  bind works!
</p>
<div [style.color]="isDev?'red':'blue'">慕課網</div>
           
isDev:boolean=true;

  constructor() {
    setTimeout(() => {
      this.isDev=false;
    }, 3000)
  }
           

設定多個内聯樣式

<p>
  bind works!
</p>
<div [ngStyle]="divStyle">慕課網</div>
           
divStyle:any={
    color:'red',
    background:'yellow'
  }

  constructor() {
    setTimeout(() => {
      this.divStyle={
        color:'yellow',
        background:'red'
      }
    }, 3000)
  }
           

雙向綁定

以前學的都是單向綁定,比如事件是從模闆到控制器

屬性綁定是從控制器到模闆

<p>
  bind works!
</p>
<input (input)="doOnInput($event)">
<input [value]="name">
           
name:string;

doOnInput(event) {

  }
           

但有時候我們想讓這兩種綁定同時生效

<p>
  bind works!
</p>
<input [value]="name" (input)="doOnInput($event)">
{{name}}
           
export class BindComponent implements OnInit {

  name:string;

  constructor() {
    setInterval(()=>{ //從控制器到模闆
       this.name="Tom";
      }
    ,)
  }

  ngOnInit() {
  }

  doOnInput(event) {
    this.name=event.target.value;//從模闆到控制器
  }

}
           

啟動項目

我修改文本框中内容name會改變。同時每隔3秒會把頁面中的内容改為Tom。

這就實作了雙向綁定,但這樣既要寫屬性又要寫事件。很麻煩。

Angular提供了ngModule指令來簡化寫法。

修改bind.component.html

<p>
  bind works!
</p>
<input [(ngModel)]="name">
{{name}}
           

這樣也會實作前面的那種效果。

報了個錯誤

解決方案,在app.module.ts中加上FormsModule

import{FormsModule} from '@angular/forms'

 imports: [
    BrowserModule,
    FormsModule
  ],