AngularJS 4(二)【模版語法,元件】

風靈使發表於2018-08-24

模板語法(Template Syntax)

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

@Component({
  selector: 'app-root',
  template: '<h1>{{title}}</h1>',
})
export class AppComponent {
  title = 'Welcome to Anglar';
  name = 'Tom';
  age = 22;
  id = '001';
  className = 'class1';
  actived = true;
  mySize = 100;
}

插值表示式

把文字內容繫結到插值字串(如”Hello Seabiscuit”)

<h1>{{title}}</h1>

屬性繫結

  1. 元素直接繫結常量:
<input type="text" title="form">
  1. 元素自身屬性繫結變數:
<input type="text" [name]="name" [id]="id" >
  1. 元素自定義屬性繫結:
<div [attr.age]="age"></div>

元素類名 class 繫結

  1. 繫結樣式名稱為變數
<div [class]="className"></div>  
  1. 根據表示式來決定 className 出不出現在元素上
<div [class.className]="1 == 1"></div>    

元素內聯樣式繫結:

<div [style.width.px]="mySize" [style.color]="'red'"></div>

元素事件繫結:

<input type="button" value="confirm" (click)="confirm($event, args)"/>

雙向繫結

該指令用於表單元素,所以在使用的時候要在根模組中 ./src/app/app.module.ts 新增表單模組 FormsModule

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

@NgModule({
    imports: [FormsModule, BrowserModule]
})
<input type="text" [(ngModel)]="name" />

本地變數

<h1>{{name.value}}</h1>
<input type="text" [(ngModel)]="name" #name/>

建立簡單的元件

  1. 建立檔案
    ./src/app 目錄下手動建立或者在 Angular-CLI 中用命令
    ng g c [component-name] -it -is # 表示新建元件,該元件使用內聯模板和內聯樣式
    執行上面命令後會在 ./src/app 目錄下自動建立對應的元件目錄和元件檔案,同時會修改 src/app/app.module.ts 檔案,將新建的元件新增到 @NgModuledeclarations 陣列中。

  2. 編寫元件程式碼

//載入元件裝飾器
import { Component } from '@angular/core';
//@Component裝飾器為元件提供了Angular後設資料。
@Component({
  selector: 'app-root', //用來渲染元件內容的選擇器
  templateUrl: './app.component.html',//載入 html
  template:'<h1>{{title}}</h1>',
  styleUrls: ['./app.component.css'] //載入 css
  styles: ['*{padding: 0; margin: 0;}']
})
//總是export這個元件類,因為你必然會在別處import它。
export class AppComponent {
  title = 'Tour of Heroes'; //定義變數
}

3.在根模版 ./src/app.module.ts 中將指令新增到 declarations 陣列當中

import { HeroDetailComponent } from './components/hero-detail/hero-detail.component';
@NgModule({
    declarations: [HeroDetailComponent]
})

4.使用元件

<app-root></app-root>

元件模板

在元件裝飾器中用 templatetemplateUrl 來定義元件模板,兩者只能出現一個,如果兩者同時出現,後者會覆蓋前者。

元件樣式

在元件裝飾器中用 stylesstyleUrls 來定義元件樣式,兩者只能出現一個,如果兩者同時出現,後者會覆蓋前者。

把樣式加入元件有以下幾種方式:

styles

@Component({
  selector: 'app-root',
  template: `<h1>App</h1>`,
  styles: ['h1 { font-weight: normal; }']
})
export class AppComponent {
/* . . . */
}

styleUrls

@Component({
  selector: 'app-root',
  template: `<h1>App</h1>`,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
/* . . . */
}

模板內聯樣式

@Component({
  selector: 'app-root',
  template: `
    <style>
      button {
        background-color: white;
        border: 1px solid #777;
      }
    </style>
    <h3>Controls</h3>
    <button (click)="activate()">Activate</button>
    `
})
export class AppComponent {
/* . . . */
}

模板中的link標籤

@Component({
  selector: 'app-root',
  template: `
    <link rel="stylesheet" href="assets/app.component.css">
    <h3>Team</h3>
    <ul>
      <li *ngFor="let member of hero.team">
        {{member}}
      </li>
    </ul>
    `
})
export class AppComponent {
/* . . . */
}

CSS @imports 語法

@import 'hero-details-box.css';

元件生命週期

指令和元件的例項有一個生命週期:新建、更新和銷燬。 通過實現一個或多個 Angular core庫裡定義的生命週期鉤子介面

每個介面都有唯一的一個鉤子方法,它們的名字是由介面名再加上ng字首構成的。如:OnInit

import { Component, OnChanges, OnInit, DoCheck, OnDestroy } from '@angular/core';
export class AppComponent implements OnChanges, OnInit, DoCheck, OnDestroy {
    ngOnChanges(){}

    ngOnInit(){}

    ngDoCheck(){}

    ngOnDestroy(){}
}

OnChanges

  • Angular(重新)設定資料繫結輸入屬性時響應。 該方法接受當前和上一屬性值的SimpleChanges物件。
  • 當被繫結的輸入屬性的值發生變化時呼叫,首次呼叫一定會發生在ngOnInit()之前。

OnInit

  • Angular第一次顯示資料繫結和設定指令/元件的輸入屬性之後,初始化指令/元件時觸發。
  • 在第一輪 ngOnChanges() 完成之後呼叫,只呼叫一次。
  • onDestroy() 後重新渲染後會被呼叫。

AfterContentInit

  • 當把內容投影進元件之後呼叫。第一次ngDoCheck()之後呼叫,只呼叫一次。
  • 只適用於元件。

DoCheck

  • 使用DoCheck鉤子來檢測那些Angular自身無法捕獲的變更並採取行動。如引用型別的賦值。
  • 給元件賦值同一個物件的時候,不會觸發 OnChanges,但會觸發 DoCheck

AfterContentChecked

  • 每次完成被投影元件內容的變更檢測之後呼叫。
  • ngAfterContentInit()和每次ngDoCheck()之後呼叫。
  • 只適用於元件。

OnDestroy

  • Angular每次銷燬指令/元件之前呼叫並清掃。 在這兒反訂閱可觀察物件和分離事件處理器,以防記憶體洩漏。
  • Angular銷燬指令/元件之前呼叫。
  • 沒有對應的銷燬後鉤子函式。

AfterViewInit

  • Angular會在每次建立了元件的子檢視後呼叫它們。
  • 可用於監聽子元件載入完成。

AfterViewChecked

  • Angular 會在每次子檢視修改後會呼叫它們。
  • 可用於監聽子元件修改完成。

元件通訊

通過 @Input 實現子元件呼叫父元件

父元件定義

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

export class Hero {
    id: number;
    name: string;
}

const HEROES: Hero[] = [
  { id: 11, name: 'Mr. Nice' },
  { id: 12, name: 'Narco' },
  { id: 13, name: 'Bombasto' },
  { id: 14, name: 'Celeritas' },
  { id: 15, name: 'Magneta' },
  { id: 16, name: 'RubberMan' },
  { id: 17, name: 'Dynama' },
  { id: 18, name: 'Dr IQ' },
  { id: 19, name: 'Magma' },
  { id: 20, name: 'Tornado' }
];
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent{
  heroes = HEROES;
  currHero: Hero;

  selectHero(hero: Hero) {
    this.currHero = hero;
  }  
}

父元件的 template 並在裡面呼叫子元件

<ul class="heroes">
    <li *ngFor="let hero of heroes" (click)="selectHero(hero)">
        <span class="badge">{{hero.id}}</span>{{hero.name}}
    </li>
</ul>
<hero *ngIf="currHero" [currHero]="currHero"></hero>

子元件定義


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

@Component({
  selector: 'hero',
  templateUrl: './hero.component.html',
  styleUrls: ['./hero.component.css']
})
export class HeroComponent{
  @Input() currHero: Object;
}

子元件的 template

<div *ngIf="currHero">
  <h2>{{currHero.name}} details!</h2>
  <div><label>id: </label>{{currHero.id}}</div>
  <div>
    <label>name: </label>
    <input [(ngModel)]="currHero.name" placeholder="name"/>
  </div>
</div>

通過 @Output 實現父元件呼叫子元件

子元件暴露一個EventEmitter屬性,當事件發生時,子元件利用該屬性emits(向上彈射)事件。父元件繫結到這個事件屬性,並在事件發生時作出迴應。

子元件的EventEmitter屬性是一個輸出屬性,通常帶有@Output裝飾器,就像在VoterComponent中看到的。

父元件定義

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent{
  parentEvent(val: Boolean){
    console.log(val);
  }
}

父元件的 template 並在裡面呼叫子元件

<hero (parentAttr)="parentEvent($event)"></hero>

子元件定義

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

@Component({
  selector: 'hero',
  templateUrl: './hero.component.html',
  styleUrls: ['./hero.component.css']
})
export class HeroComponent{
  @Output() parentAttr = new EventEmitter<Boolean>();
  childrenEvent(val: Boolean){
    this.parentAttr.emit(val);
  }
}

子元件的 template

<button (click)="childrenEvent(true)">Agree</button>

父元件與子元件通過本地變數互動

父元件定義

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent{
  parentEvent(arg1){
    console.log(arg1);
  }
}

父元件的 template 並在裡面呼叫子元件

<button (click)="parentEvent(childrenComponent)">Stop</button>
<hero #childrenComponent></hero>

子元件定義

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

@Component({
  selector: 'hero',
  templateUrl: './hero.component.html',
  styleUrls: ['./hero.component.css']
})
export class HeroComponent{
  title = "Children Component";
}

通過服務來通訊

相關文章