摘要:正文架構概覽正文架構概覽接觸大概一個月吧,期間寫了個項目,趁現在稍微有點時間,來回顧梳理一下。里的模塊,并不等同于項目中的模塊概念。當然,這只是我目前階段的理解。
本系列文章內容梳理自以下來源:
官方的教程,其實已經很詳細且易懂,這里再次梳理的目的在于復習和鞏固相關知識點,剛開始接觸學習 Angular 的還是建議以官網為主。
因為這系列文章,更多的會帶有我個人的一些理解和解讀,由于目前我也才剛開始接觸 Angular 不久,在該階段的一些理解并不一定是正確的,擔心會有所誤導,所以還是以官網為主。
接觸 Angular 大概一個月吧,期間寫了個項目,趁現在稍微有點時間,來回顧梳理一下。
其實,如果前端網站并不是特別復雜,那么使用 Angular 無非也就是常跟幾個重要的知識點打交道,在官網的核心知識的第一節(jié)中就將這些知識點羅列出來了,也就是:架構概覽。
畫了這個圖來大概表示下 Angular 的架構概覽,基本涉及到一些常見的重要的知識點了,比如:
不同的類型,文件名通常會都按照一定的規(guī)范來命名,以便直接看出該文件的角色。
當然,文件命名只是給開發(fā)人員來方便維護、辨別,對于 Angular 來說,這些都是一份份的 ts 文件代碼,所以,都需要在相對應的文件中加上一些裝飾器比如:@Directive,@Pipe,@Component,@NgModel 等這些,才能夠讓 Angular 識別出該文件的角色、用途。
基本上,用 Angular 做一個簡單的前端項目,就是跟上面這些打交道,理清它們各自的用途及用法,還有之間的聯(lián)系,基本上,就可以上手進行一些開發(fā)了。
當然,像在 Service 服務中,還會有異步編程、HttpClient 網絡編程的相關知識點;
在 Component 組件中,也還會有表單、動畫相關的編程知識點,這些都是需要進一步去深入學習研究,但從總體架構上來看,就是要先了解以上這些知識點了。
一個 Angular 項目,至少會有一個模塊,即最少都會有一份用 @NgModel 聲明的 ts 文件,表明該文件作為模塊角色,來管理其他角色。
其他角色包括:組件、指令、管道、服務等等,這些角色必須在模塊文件中聲明了,才能夠被該模塊內的其他角色所使用,而且同一個組件、指令、管道不允許同時在多個模塊中進行聲明,只能通過模塊 exports 給其他模塊使用。
Angular 里的模塊,并不等同于 Android 項目中的模塊概念。
在 Android 項目代碼中,可能我們會根據功能來進行模塊的劃分,但這個模塊僅僅是抽象上的概念,也就是建個包,把代碼都集中管理。
而 Angular 里的模塊,不僅可以在項目結構上集中管理同一個模塊的代碼文件,還可以為模塊內的代碼提供一個運行的上下文。
意思就是說,不同模塊在運行期間互不影響,就好像各自運行在各自的沙箱容器中一樣。舉個簡單的例子,在不同模塊中聲明相同的變量名,或相同的 css 的類選擇器,它們之間并不會起沖突。
當然,模塊之間可以有交互,模塊可以依賴于另一模塊,模塊內的可以共享資源等等,所以,NgModel 中有許多需要配置的聲明項,比如:
在 Angular 中,大多數的模式就是,一個根模塊管理著很多功能模塊,然后,每個模塊管理自己模塊內部所使用到的組件、指令、管道、服務、或者需要依賴于其他模塊,如果該模塊內部的這些角色,有些可以供其他模塊使用,那么就需要對外暴露。
一個項目這么多模塊,Angular 并不會一開始就把所有模塊都加載,而是惰性加載,按需加載。
那么,什么時候會去加載呢?
就是等某個模塊內部的組件被使用的時候會加載,而組件是什么時候會被使用的呢?
有兩個時機,一是組件被直接調用;二是觸發(fā)了路由去加載;
路由通常的配置方式是用一個 @NgModel 聲明的模塊,但只用其中兩項配置:imports 和 exports,imports 用來導入當前模塊所有組件與 url 的映射表,而 exports 用來將這些映射表信息暴露,以供相對應的模塊去引入使用。
當然,你不想抽離路由配置,直接將其配置在對應模塊的 imports 內也可以,抽離的話,相對獨立,可維護。
區(qū)別于傳統(tǒng)的前端網頁的跳轉方式,Angular 項目是一個單頁應用,所謂的單頁應用就是說只有一個頁面,所有頁面的跳轉,其實是將當前頁面的顯示內容進行替換,頁面仍舊只有一個,并不會打開新的頁面。
而頁面的跳轉,通常有以下幾種場景:
這些場景,路由的工作機制都能夠很好的支持。
如果網頁很簡單,只有一個首頁,并不存在頁面跳轉場景,那么可以不用配置路由,只需要在 index.html 中配置根視圖,以及在根模塊的 bootstrap 中配置根視圖組件即可。
但如果項目劃分成了多個功能模塊,那么應該交由每個模塊管理自己的路由表,而后選擇一個上層模塊,來統(tǒng)一關聯(lián)各個模塊路由,有兩種方式:一是在上層模塊的 imports 內按照一定順序來導入各個功能模塊;但這種方式想要按照路由層級來查看路由表就比較麻煩,需要到各個模塊內部去查看或者借助一些工具。
另一種方式是,在上層模塊的路由表中使用 loadChildren 加載各個功能模塊,然后各個功能模塊默認路由都顯示成空視圖,各自內部再通過配置 children 的路由表方式來管理各個模塊內部自己的路由表。
在 Angular 中,最常接觸的應該就是組件了。
我是這么理解的,組件可以是你在界面上看到的任何東西,可以是一個頁面,可以是頁面上的一個按鈕。
而對于瀏覽器解析并呈現前端頁面時,Html、CSS、JavaScript 這三分文件通常都是需要的,而 Angular 是使用了 TypeScript,所以一個組件,其實就包括了:Html,CSS,TypeScript。
在 Angular 中,可以說,是以組件為單位來組成頁面的,組件是核心,因為 Angular 提供的功能基本都是用來為組件服務的。
以上,是我的理解。
但要注意,官網教程中,很多地方的組件描述,更多時候是傾向于表示 TypeScript 的那份文件,因為對于組件來說,TypeScript 可以說是它的核心,CSS 只是樣式文件,Html 更類似于模板存在。
所以這里將組件和模板放在一起講,因為就像開頭那張圖一樣,組件是一份 TypeScript 文件,在該文件中,定義了這個組件的模板(template)來源和 CSS 樣式來源。
模板提供了該組件的呈現結構,而 TypeScript 里定義了組件的數據來源及交互行為,它們兩一起組織成一個視圖呈現給用戶。
既然,這份 TypeScript 的組件文件和模板文件需要共同合作,那么它們之間就少不了交互,所以就涉及到很多所謂的模板語法,也就是所謂的組件和模板之間的交互方式。
比如,當要往模板中嵌入 TypeScript 中的變量數據時,可以使用 {{value}}
這種語法形式,同樣的,還有模板中標簽的屬性綁定,事件回調注冊的交互方式的語法。
總之,Angular 支持雙向數據綁定,是一種以數據驅動的思想來讓頁面進行交互刷新的方式,區(qū)別于傳統(tǒng)的前端模式。在以往,如果需要動態(tài)的更新 DOM 上的信息時,需要先獲取到相對應的元素實例對象,然后調用相應的 DOM API 來操縱 DOM;
而使用 Angular 的話,可以直接在模板的相應元素中,將某個屬性與 TypeScript 文件中某個變量直接進行綁定,后續(xù)這個變量值變化時,Angular 會自動去更新相應 DOM 的屬性,也就是說,原本那些操縱 DOM 的代碼,Angular 幫我們做了,我們不用再自己去處理了。
另外,注意,以上出現的 TypeScript 的描述,你可以理解成官網中的組件,我之所以不想用組件的方式來進行描述,是因為,我覺得,組件是一個整體,它本身就包括了 TypeScript 文件和模板文件,所以官網中說的組件和模板的交互,我覺得,換成組件中的 TypeScript 文件與模板文件的交互更為適合。
當然,這只是我目前階段的理解。
服務是一個廣義上的概念,通常用來處理那些跟 UI 交互無關的事情,比如網絡請求的工作等。
所以它也是為組件服務,而且 Angular 有一套依賴注入機制,也就是說,組件只需要告訴 Angular,它需要哪些服務,至于這些服務的實例是什么時候創(chuàng)建,交給誰去管理等這些組件內部都不用自己去處理了。
Angular 會自動創(chuàng)建相關的服務實例,然后在組件適當的時候,將這個實例注入給組件去使用。
這種模式跟以前在 Android 端開發(fā)時有所區(qū)別,在 Android 端中,當需要業(yè)務層某個實例對象時,通常都需要自己內部去初始化,或者這個實例是個單例的話,也需要自己去實現單例。
但在 Angular 中,你可以借助它依賴注入的機制,來讓 Angular 幫你去做這些依賴的對象的實例管理的事,如果需要一個全局的單例服務,那么可以將該服務聲明成 root 即全局可用;如果需要一個模塊內的單例,那么可以在該模塊的 providers 中聲明該服務;如果需要一個組件自己的實例對象,那么可以在組件的元數據塊的 providers 中配置該服務。
總之,就是,跟 UI 交互無關的工作,可以抽到服務中去處理,而該服務實例的管理,交給 Angular 就可以了,組件只需要告訴 Angular 它需要哪種形式的服務即可。
那么,組件是怎么告訴 Angular 的呢?
同樣在 Android 項目或者后端項目中,也有一些依賴注入框架,那些通常都是借助注解的方式來實現。
但在 Angular 中,不用這么麻煩,直接在組件的構造函數的參數中,聲明某個服務類型的參數即可。
指令也是為組件服務的,但是,是在組件的模板文件中來使用。
因為組件的模板,其實就是一份 HTML 文件,基于 HTML 的標簽之上,加上一些 Angular 的模板語法,而 Angular 在將這份 HTML 文件代碼交給瀏覽器解析之前,會先自行解析一遍,去將模板中不屬于 HTML 的那些語法解析出相應的行為。
而指令分為結構型指令和屬性型指令,它們的區(qū)別,其實就在于,一個是改變 DOM 的結構,一個是改變 DOM 元素的樣式。
所以說,指令的目的,其實就是簡化一些操縱 DOM 的工作,比如你需要讓某些按鈕都具有統(tǒng)一的行為和樣式,當被點擊時先做什么,再做什么。
實現這個,你當然可以在 TypeScript 中去書寫這些邏輯,但要應用到每個按鈕上,就比較繁瑣。
這個時候,就可以將這些工作都封裝到指令內部,然后在每個按鈕標簽上加上該指令,Angular 在解析模板時,發(fā)現了這個指令,就會為每個按鈕都加上這么一段程序邏輯。
我個人覺得,指令的功能,讓我們處理一些相同的行為,可以更好的去封裝,減少冗余和繁瑣。
當然,上面舉的場景,也可以自己封裝個按鈕組件,然后在其他模板中,不使用原生按鈕,而使用封裝后的按鈕組件,也可以達到目的。
所以,組件其實也是指令的一種,但組件的實現方式會比較重,有時候,只需要封裝一些簡單的行為邏輯,就可以直接借助指令的方式封裝。
指令的原理也很簡單,在模板中某個元素標簽上,添加上某個指令后,解析到這個指令時,會進入這個指令的相關工作,而指令內部,會獲取到一個當前指令掛載的元素標簽對象,既然都拿到這個對象了,那么,在指令內部想對這個元素做什么,都可以了。
指令還有另一個通途,通常用來擴展原有的功能,因為可能項目中,在模板里使用的組件或者 HTML 元素的標簽因為種種原生無權或不方便進行修改,而又想在其基礎上擴展一些功能,此時就可以利用指令來實現。
管道同樣是為組件服務,也同樣是在組件的模板文件中來使用。
它的用途,在于,將數據按照一定的規(guī)則進行轉換,比如 Object 對象,轉換成 json 格式數據,再比如,long 型的時間,轉換成具體的時間日期等等。
Angular 中已經內置了一些管道,也可以自定義管道。
大概了解了 Angular 的架構概覽,接下去就來看看一個簡單的 Angular 項目結構,以及各個文件、模塊的用途,稍微講一下。
這是用 WebStrom 創(chuàng)建一個 Angular 項目后,自動生成的簡單架構。
在利用 Angular Cli 工具生成腳手架時,默認就已經生成了很多配置項,而且此時,項目已經是可以運行的,因為也自動生成了一個根模塊和根視圖,默認頁面是 Angular 的歡迎界面。
挑幾個來講講。
這是 Angular-CLI 的配置文件,而 Angular-CLI 是自動化的工程構建工具,也就是利用這個工具,可以幫助我們完成很多工作,比如創(chuàng)建項目、創(chuàng)建文件、構建、打包等等。
原本的 HTML、CSS、JavaScript 的前端開發(fā)模式,并沒有工程的概念,只要用瀏覽器打開 HTML 文件就能夠運行。而 Angular 引入了 TypeScript,Scss 等瀏覽器并不無法識別的語言,自然,要讓瀏覽器運行 Angular 項目之前,需要進行一次編譯,一次轉換。
這些工作就可以借助 Angular-CLI 來進行。另外,創(chuàng)建一個模塊,創(chuàng)建一個組件,也都可以通過 Angular-CLI 來。
那么,在創(chuàng)建這些文件或者說,打包編譯這些項目文件時,該按照怎樣的規(guī)則,就是參照 angular.json 這份配置文件。
大概看一下內容:
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json", // 默認的配置項,比如默認配置了 ng g component 生成組件時應該生成哪些文件等等
"version": 1,
"newProjectRoot": "projects",
"projects": {
"daView": { // 項目的配置
"root": "",
"sourceRoot": "src", // 源代碼路基
"projectType": "application", // 項目的類型,是應用還是三方庫(library)
"prefix": "app", // 利用命令生成 component 和 directive 的前綴
"schematics": {}, // 替換掉第一行的 schema.json 中的一些默認配置項,不如創(chuàng)建組件時,不要生成spec文件
"architect": { // 執(zhí)行一些構造工作時的配置
"build": { // 執(zhí)行 ng build 時的一些配置項
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/daView", // 編譯后的文件輸出的位置
"index": "src/index.html", // 構建所需的模板 Index.html
"main": "src/main.ts", // 構建所需的文件
"polyfills": "src/polyfills.ts", // 構建所需的文件
"tsConfig": "src/tsconfig.app.json", // 對 typescript 編譯的配置文件
"assets": [ // 構建所需的資源
"src/favicon.ico",
"src/assets"
],
"styles": [ // 構建所需的樣式文件,可以是 scss
"src/styles.css"
],
"scripts": [] // 構建所需的三方庫,比如 jQuery
},
"configurations": {/*...*/}
},
"serve": {/*...*/}, // 執(zhí)行 ng serve 時的一些配置項
"extract-i18n": {/*...*/},
"test": {/*...*/},
"lint": {/*...*/}
}
}
},
"daView-e2e": {/*...*/},
"defaultProject": "daView"
}
所以,利用 Angular-CLI 生成的初始項目中,有許多基本的文件,這些文件,基本也都在 angular.json 中被配置使用了,每個配置文件基本都有各自的用途。
比如,tslint 用來配置 lint 檢查,tsconfig 用來配置 TypeScript 的編譯配置,其他那些 html,css,ts,js 文件基本都是 Angular 項目運行所需的基礎文件。
對于一個工程項目來說,依賴的三方庫管理工具也很重要,在 Android 項目中,通常是借助 Gradle 或 maven 來管理三方庫。
而在 Angular 項目中,是使用 npm 來進行三方庫的管理,對應的配置文件就是 package.json。
在這份配置文件中,配置了項目所需要的三方庫,npm 會自動去將這些三方庫下載到 node_modules
目錄中。然后,再去將一些需要一起打包的三方庫在 angular.json 中進行配置。
以上就是利用 Angular-CLI 創(chuàng)建項目生成的初始架構中各個文件的大概用途,下面講講 Angular 項目的大概運行流程。
在 src 中的 index.html
文件就是單頁應用的頁面文件,里面的 body 標簽內,自動加入了一行根視圖的組件:
就是根組件 AppComponent (自動生成的)的組件標簽,當 Angular 在 HTML 文件中發(fā)現有組件標簽時,就會去加載該組件所屬的模塊,并去解析組件的模板文件,將其嵌入到 HTML 文件的組件標簽中。
看一下自動生成的根模塊的部分內容:
//app.module.ts
import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";
import { AppComponent } from "./app.component";
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
//app.component.ts
import { Component } from "@angular/core";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
title = "daView";
}
app.module.ts
文件用 @NgModule 表示該文件角色是模塊,并在內部配置了它的組件 AppComponent,這樣 AppComponent 組件就只屬于該模塊了,并能夠在該模塊內的其他組件中被使用。
另外,由于該模塊是根模塊,所以還需要配置 bootstrap,設置應用的根視圖,這個配置需要和 index.html
里的 body 標簽內的根視圖組件是同一個組件,否則運行時就會報錯了。
當項目中模塊多了的時候,各模塊之間基本是通過路由或者組件來進行相互關聯(lián)。
比如,我們新創(chuàng)建個 Home 模塊,然后在根模塊中創(chuàng)建個 app-routing 路由配置文件:
//app-routing.module.ts
import { NgModule } from "@angular/core";
import { Routes, RouterModule } from "@angular/router";
const routes: Routes = [
{
path: "home", loadChildren: "./home/home.module#HomeModule"
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
然后在 app.module.ts 的 imports 中將該路由配置導入,這樣當路由到 home 時,會去加載 home 模塊,然后看看 home 模塊的路由配置:
//home-routing.module.ts
import { NgModule } from "@angular/core";
import { Routes, RouterModule } from "@angular/router";
import {HomeComponent} from "./home.component";
import {HomeCenterComponent} from "./component/home-center.component";
const routes: Routes = [
{
path: "",
children: [
{
path: "", component: HomeCenterComponent
}
]
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class HomeRoutingModule { }
home 模塊的默認視圖為空,但交由其子視圖來控制,所以,當導航到 home 時,home 模塊會去加載它內部的 HomeCenterComponent 組件。
以上,是當項目中有多模塊時,我的處理方式。
當按照這種方式來實現時,對于了解一個 Angular,就有一定的規(guī)律可循了:
大家好,我是 dasu,歡迎關注我的公眾號(dasuAndroidTv),公眾號中有我的聯(lián)系方式,歡迎有事沒事來嘮嗑一下,如果你覺得本篇內容有幫助到你,可以轉載但記得要關注,要標明原文哦,謝謝支持~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/1129.html
摘要:責編現代化的方式開發(fā)一個圖片上傳工具前端掘金對于圖片上傳,大家一定不陌生。之深入事件機制前端掘金事件綁定的方式原生的事件綁定方式有幾種想必有很多朋友說種目前,在本人目前的研究中,只有兩種半兩種半還有半種的且聽我道來。 Ajax 與數據傳輸 - 前端 - 掘金背景 在沒有ajax之前,前端與后臺傳數據都是靠表單傳輸,使用表單的方法傳輸數據有一個比較大的問題就是每次提交數據都會刷新頁面,用...
angular2.0 學習筆記 ### 1.angular-cli 常用命令記錄 詳細教程 angular cli官網 有,這里不詳細說明,感興趣的可以自行到官網看,一下僅記錄本人到學習過程常用到的命令 1.創(chuàng)建項目 ng new ng new project-name exp: ng new my-app 2.啟動項目 ng serve 參數名 類型 默認值 作用 exp ...
摘要:感謝王下邀月熊分享的前端每周清單,為方便大家閱讀,特整理一份索引。王下邀月熊大大也于年月日整理了自己的前端每周清單系列,并以年月為單位進行分類,具體內容看這里前端每周清單年度總結與盤點。 感謝 王下邀月熊_Chevalier 分享的前端每周清單,為方便大家閱讀,特整理一份索引。 王下邀月熊大大也于 2018 年 3 月 31 日整理了自己的前端每周清單系列,并以年/月為單位進行分類,具...
摘要:下一篇譯精通使用開發(fā)二原版書名第一章之道這一章主要是介紹,包括這個框架以及它背后的項目。幸運的是,擁有一個活躍的,支持度高的社區(qū)。另外,社區(qū)還為已經存在的工具箱里貢獻了許多有意思的工具。 下一篇:【譯】《精通使用AngularJS開發(fā)Web App》(二) 原版書名:Mastering Web Application Development with AngularJS Ch...
閱讀 3318·2023-04-25 16:25
閱讀 3823·2021-11-15 18:01
閱讀 1600·2021-09-10 11:21
閱讀 3007·2021-08-02 16:53
閱讀 3081·2019-08-30 15:55
閱讀 2489·2019-08-29 16:24
閱讀 2098·2019-08-29 13:14
閱讀 1027·2019-08-29 13:00