從flask視角理解angular(二)Blueprint VS Component
Component類似flask app下面的每個blueprint。
import ‘rxjs/add/operator/switchMap‘; import { Component, OnInit } from ‘@angular/core‘; import { ActivatedRoute, ParamMap } from ‘@angular/router‘; import { Location } from ‘@angular/common‘; import { Hero } from ‘./hero‘; import { HeroService } from‘./hero.service‘; @Component({ selector: ‘hero-detail‘, templateUrl: ‘./hero-detail.component.html‘, styleUrls: [ ‘./hero-detail.component.css‘ ] }) export class HeroDetailComponent implements OnInit { hero: Hero; constructor( private heroService: HeroService, private route: ActivatedRoute, private location: Location ) {} ngOnInit():void { this.route.paramMap .switchMap((params: ParamMap) => this.heroService.getHero(+params.get(‘id‘))) .subscribe(hero => this.hero = hero); } goBack(): void { this.location.back(); } }
@Component 說明了兩個路徑,
1 /templates/每個blueprint下的用 jinja2 語法的XXX.html,2 /static/下的 css
也可以直接把模板內容和css直接寫在@Component下面,這時Component有點類似Unity3d裏的gameobject,@Component裏面的“selector,template” 有點類似gameobject裏的“transfrom”,"material"。(U3d裏是gameobject->component 不要和ng的Component混了)。
區別在於:flask強調"動靜分離"。這樣部署的時候,static部分用nginx, web api部分 用 gunicorn。
angular的“前後端”統統用ts/js搞了。這樣開發者不需要太在乎“動靜”與“前後"的分野。封裝程度類似unity3d裏的prefab,感覺很不錯。
定義
每次開頭都要導入Component
import { Component } from ‘@angular/core‘;
類似blueprint:
from flask import Blueprint
導出
export class AppComponent {
title = ‘Tour of Heroes‘;
hero = ‘Windstorm‘;
}
類似
user_blueprint = Blueprint(‘user‘, __name__, url_prefix=‘/user‘)
OnInit
不同於構造函數constructor。
import { OnInit } from ‘@angular/core‘; export class AppComponent implements OnInit { ngOnInit(): void { } }
感覺constructor類似於python的__new__() 而ngOnInit()類似於通常使用的__init__(
self
)
看介紹:
只要我們實現了 Angular 的 ngOnInit 生命周期鉤子,Angular 就會主動調用這個鉤子。 Angular提供了一些接口,用來介入組件生命周期的幾個關鍵時間點:剛創建時、每次變化時,以及最終被銷毀時。
又有點像unity3d的Monobehaviour的 Awake() Start() Update()...由引擎在特定時機調用調用。
——不要被生命周期鉤子(lifecycle hook)之類的名詞嚇倒。
在實幹派野生程序員這裏,不要過於在意這些唬人的新名詞。
要敢於看它是怎麽回事,然後類比到自己熟悉的概念和機制上,軟件工程的世界裏,沒有那麽多概念,範疇級的發明創造。
在python裏,可以不需要知道__init__(
self
)是不是構造函數,反正當構造函數來用;
在unity3d裏不需要糾結Awake() Start()該叫什麽名,反正大概知道該塞什麽進去就OK了。
命名
註意命名方法 HeroDetailComponent 大概類似於把藍圖對象命名為HeroDetailBlueprint
文件名和組件名遵循風格指南中的標準方式。
組件的類名應該是大駝峰形式,並且以
Component
結尾。 因此英雄詳情組件的類名是HeroDetailComponent
。The component class name should be written in upper camel case and end in the word "Component". The hero detail component class is
HeroDetailComponent
.組件的文件名應該是小寫中線形式,每個單詞之間用中線分隔,並且以
.component.ts
結尾。 因此HeroDetailComponent
類應該放在hero-detail.component.ts
文件中。
引用Componet視圖
父組件AppComponent
會告訴子組件HeroDetailComponent
要顯示哪個英雄, 告訴的方法是把它的selectedHero
屬性綁定到HeroDetailComponent
的hero
屬性上。
這種綁定(協調主視圖AppComponent與HeroDetailComponent的方式)是這樣的:
<hero-detail [hero]="selectedHero"></hero-detail>
在等號的左邊,是方括號圍繞的hero
屬性,這表示它是屬性綁定表達式的目標。 我們要綁定到的目標屬性必須是一個輸入屬性,否則Angular會拒絕綁定,並拋出一個錯誤。
1 把
AppComponent
的selectedHero
屬性綁定到HeroDetailComponent
的input 屬性hero
上。表示了傳輸關系2 <hero-detail>是HeroDetailComponent 的 @Component裏的selector。
這樣的好處是,不用在AppComponent裏顯示引用HeroDetailComponent。只要[hero]是declaration過的某個Component裏的input屬性就OK了。
——這個比較別扭但又很巧妙。
從flask視角理解angular(二)Blueprint VS Component