你是否曾經感到困惑,不知道該選擇React、Angular還是Vue.js或是jQuery?別擔心,這系列將為你深入解說這三個最受歡迎的前端框架,從學習曲線、性能、社區支持、適用場景等多個方面進行詳細解說,以幫助你做出明智的選擇。Angular基本概念解析Angular是一個強大的前端框架,它的存在是為了讓前端開發變得更加容易且有組織性。它提供了一個強大的架構,幫助開發者構建互動性豐富的網頁應用程式。什麼是Angular?Angular是一個開源的前端框架,由Google開發和維護。它的主要目標是簡化前端開發,提供一個有組織的方法來構建Web應用程式。Angular使用TypeScript作為主要的程式語言,這使得代碼更具可維護性和可擴展性。Angular不僅僅是一個JavaScript框架,它還包括了一個豐富的生態系統,如AngularCLI、AngularMaterial和NgRx。Angular的主要特點之一是它的組件化架構,讓開發者可以將應用程式拆分為多個獨立的組件,每個組件都有自己的視圖和邏輯,這使得代碼結構更清晰且易於維護。為什麼選擇Angular?Angular提供了許多優點,這些優點使其成為許多人前端開發的首選框架:豐富的生態系統:Angular生態系統包括了許多強大的工具、庫和插件,簡化了各種任務。不管是路由管理、狀態管理、UI設計,還是測試。這意味著你可以以更高效的方式完成任務。模組化架構(Modularity):Angular採用了模組化架構,這是一個重要的設計。你可以將相關的代碼打包成一個模組,使代碼更具結構性和可維護性。使你的應用程式更容易測試、維護和擴展。你可以將功能模組化,並在需要時輕鬆地將其添加到你的應用中。數據雙向綁定(TwoWayDataBinding):Angular引以為傲的一個特點是數據雙向綁定。你的應用程式的模型(Model)和視圖(View)之間有一個動態交集,任何變化都會可以立即反映在視圖中。當你在搜尋框中輸入文字時,不僅會即時顯示搜索結果,連你的URL也會同步更新。讓你的應用程式更具互動性。強大的模板系統:Angular的模板系統提供了一種簡易的方式來創建動態與靜態模板。你可以輕鬆地將數據顯示在模板中,並使用指令來操作DOM。使你可以創建美觀且高度互動的用戶界面,而不必過多的手動操作DOM。強大的型別檢查:Angular使用TypeScript作為主要的程式語言,受益於靜態型別檢查。開發時,TypeScript將幫助你捕獲潛在的錯誤,從而減少錯誤並提高代碼質量。依賴注入(DependencyInjection):Angular引入了依賴注入,這是一個重要的設計模式。允許你將服務(Services)或其他代碼注入到你的組件(Components)中,這使得代碼更具可測試性且解耦。你可以在應用程式中輕鬆共享和重用代碼,並實現更好的代碼結構。內建指令和過濾器:Angular提供了許多內建指令(例如:ngFor、ngIf等)和過濾器(例如:date、currency等),它們使你可以輕鬆地操作DOM和格式化數據。減少了重複的代碼,並代碼更加整潔。建立你的第一個網路應用安裝Node.js和npm:Angular開發需要使用Node.js和npm,你可以從Node.js官方網站]https://nodejs.org/zhtw下載並安裝它。安裝AngularCLIAngularCLI(命令行界面)是一個強大的工具,可以幫助你快速建立和管理Angular專案。讓我們安裝它,在終端機中運行以下命令:npminstallg@angular/cli這個指令將全局安裝AngularCLI,讓你可以在任何地方使用它。安裝完成後,運行ngversion來確認一下,確保工具安裝完畢。創建你的第一個Angular應用程式使用AngularCLI,你可以輕鬆地創建一個嶄新的Angular應用程式。請在終端機中運行以下命令:ngnewfirstapp這個命令將帶領你回答一些問題,例如是否要包含Angular路由等。根據你的需求進行選擇。完成後,AngularCLI將為你創建一個全新的專案,取名為firstapp,並自動安裝所有必要的依賴項。Angular專案結構在Angular專案中,你將看到許多檔案和資料夾,它們具有不同的功能。以下是一些主要的檔案和資料夾:src/:這是你的應用程式代碼的主要目錄。src/app/:這是你的應用程式的核心代碼,包括模組、服務和模組。angular.json:這是Angular專案的配置文件,包含構建選項和全局配置。package.json:這是你的專案依賴項的清單,包括Angular相關的套件。index.html:你的應用程式的入口HTML文件。main.ts:應用程式的主入口TypeScript文件。app.module.ts:主要的應用程式模組,它定義了你的應用程式的模組和服務。啟動Angular應用程式現在,讓我們啟動開發伺服器,預覽你的Angular應用程式。在終端機中運行以下命令:ngserve這將啟動開發伺服器並在本地瀏覽器中預覽你的應用程式。預設情況下,它將運行在http://localhost:4200/上。創建、設計、與互動組件什麼是Angular組件?Angular的組件是前端應用程式的基本構建塊,想像你今天正在玩一組名為Angular的積木,每個組件都是你精心設計的元件,包含自己的工具和特殊功能,最後拼裝成一臺飛機等成果。這種模組化的設計方式使你的程式碼更有組織性,易於管理和維護。讓我們以一個實例來解釋。假設你正在打造一個現代化的電子商務網站,內含商品列表、購物車和用戶註冊功能。你可以為每個功能建立獨立的組件,例如「Products」、「Cart」和「UserRegistration」。這樣的方式使你的程式碼更清晰,每個功能都有自己的專屬工作空間,使代碼更加易於維護、管理和測試。現在,讓我們看一個實際的例子。假設你正在開發一個天氣的應用程式,你可以創建一個名為weather的組件,該組件負責顯示天氣信息。使用AngularCLI,你可以運行以下命令創建組件:Bashnggeneratecomponentweather這將創建一個名為weather的組件,並生成相應的文件和資料夾。組件的模板、邏輯和樣式通常存放在一個文件夾中,並按照以下結構組織:weather/├──weather.component.html├──weather.component.ts└──weather.component.css組件模板與樣式設計模板:賦予生命組件的模板是它的格局,就像一個店家的牆壁、管線。模板使用HTML編寫,但具有Angular的模板語法的優勢,讓你可以動態顯示數據,控制組件的外觀,以及處理事件。讓我們以weather為例,假設我們想要顯示城市的名稱、溫度和天氣狀況。以下是一個簡單的模板:htmlh1{{city}}天氣/h1p溫度:{{temperature}}°C/pp天氣狀況:{{condition}}/p在這個模板中,我們使用雙大括號{{}}的語法,將組件中的變數動態顯示在模板上。這就是數據綁定的一個範例,我們將在稍後更詳細地討論。樣式:美化你的組件每個組件都有自己的風格,就像是店家的裝潢、店面設計。通常,這些風格存放在.css或.scss檔案中。你可以在樣式檔案中定義樣式規則,然後將它們套用到組件的HTML元素上,以自訂組件的外觀。舉個例子,如果我們想要為weather添加一些樣式,我們可以這樣做:Css.weather{backgroundcolor:eee;padding:0.5rem1rem;border:0.125remsolid000;}Htmldivclass"weather"h1{{city}}天氣/h1p溫度:{{temperature}}°C/pp天氣狀況:{{condition}}/p/div在這個範例中,我們為.weather類添加了一些樣式,你可以輕鬆地設計組件的外觀,使其符合你的應用程式風格。組件間的通信在實際應用中,組件之間需要相互通信和共享數據。Angular提供了多種方式來實現組件間的通信。輸入和輸出屬性是一種常見的組件間通信方式。透過輸入屬性,你可以將資料傳遞給子組件,而透過輸出屬性,子組件則可以發送事件給父組件。我們一樣用weather的組件,寫一個cityselector來搭配做範例,當用戶在cityselector中選擇一個城市時,將該城市的名稱傳遞給weather並更新天氣信息。我們可以這樣做:首先,讓我們創建cityselector組件。cityselector.component.htmlhtmldivinputtype"text"ngModel]"selectedCity"placeholder"輸入城市名稱"buttonclick"onCitySelected"選擇城市/button/div將用戶輸入的城市名稱存儲在selectedCity變數中,並透過點擊觸發selectCity。使用ngModel]來實現雙向數據綁定,後續還需配置FormsModule,以支援雙向數據綁定。CitySelectorComponent但接下來,我們先在cityselector.component.ts中實現相關的邏輯。cityselector.component.tstypescriptimport{Component,Output,EventEmitter}from"@angular/core";@Component{selector:"appcityselector",templateUrl:"./cityselector.component.html",styleUrls:"./cityselector.component.css"]}exportclassCitySelectorComponent{@OutputcitySelected:EventEmitterstringnewEventEmitterstring;selectedCity:string"";//使用ngModel來綁定輸入框的值onCitySelected{ifthis.selectedCity{this.citySelected.emitthis.selectedCity;//發送選擇的城市名稱到父組件};};};接下來,讓我們使用weather組件來接收這個城市名稱並更新天氣信息。weather.component.tstypescriptimport{Component,Input}from"@angular/core";@Component{selector:"appweather",templateUrl:"./weather.component.html",styleUrls:"./weather.component.css"]}exportclassWeatherComponent{@Inputcity:string"";//用於顯示城市名稱temperature:string"25°C";//默认温度condition:string"晴天";//默认天气状况}在weather組件中,我們設置了city、temperature和condition屬性,用於顯示城市名稱、溫度和天氣狀況。然後,我們創建了一個onCitySelected方法,用於接收從cityselector組件傳遞過來的城市名稱,並根據城市名稱更新天氣信息。然後,在你的weather.component.html模板中,你可以使用這些屬性來顯示天氣信息。weather.component.htmlhtmldivclass"weather"h1{{city}}天氣/h1p溫度:{{temperature}}°C/pp天氣狀況:{{condition}}/p/div最後我們在主要的應用程式模組app.module.ts中導入FormsModule並配置CitySelectorComponent與WeatherComponent。app.module.tstypescript//app.module.tsimport{NgModule}from"@angular/core";import{BrowserModule}from"@angular/platformbrowser";import{FormsModule}from"@angular/forms";//導入FormsModuleimport{AppComponent}from"./app.component";import{CitySelectorComponent}from"./cityselector.component";//確保路徑正確import{WeatherComponent}from"./weather.component";//確保路徑正確@NgModule{imports:BrowserModule,FormsModule,//添加FormsModule到imports],declarations:AppComponent,CitySelectorComponent,WeatherComponent,],bootstrap:AppComponent],}exportclassAppModule{};app.component.htmlhtmlappcityselectorcitySelected"onCitySelected$event"/appcityselectorappweathercity]"selectedCity"/appweather這樣,當用戶在搜索框中輸入城市名稱時,它將被傳遞給WeatherComponent,並顯示相應的天氣信息。組件生命週期Angular組件的生命週期是開發過程中的關鍵,因為它涵蓋了組件從創建到銷毀的整個過程。這些生命週期允許你在不同階段執行自定義邏輯,以確保你的應用程序按照預期運行。Angular提供了一系列的生命週期,如ngOnInit、ngOnChanges、ngOnDestroy等,它們允許你在特定階段執行自定義邏輯。如果你需要在組件初始化時執行某些代碼,你可以使用ngOnInit:typescriptngOnInit{this.fetchWeatherInfothis.city;}在這個範例中,我們使用了一個更具描述性的函數名fetchWeatherInfo來代表獲取天氣信息的操作,這樣可以讓代碼更易讀。請確保在ngOnInit中執行的操作是輕量級的,以避免影響組件的性能。ngOnChanges通常用於監視組件的輸入屬性變化,但是在使用之前,你應該先檢查新值和舊值是否真的有變化,以避免不必要的操作。這樣可以提高性能並減少不必要的重繪。typescriptngOnChangeschanges:SimpleChanges{ifchanges.city&&changes.city.currentValue!changes.city.previousValue{this.fetchWeatherInfothis.city;}}在這個範例中,我們通過比較currentValue和previousValue來確保只有在city真正發生變化時才執行fetchWeatherInfo。最後,在組件銷毀時進行資源的清理工作,以避免內存泄漏。你可以使用ngOnDestroy來實現這一點,例如取消訂閱觀察者或清理訂閱的資源。typescriptngOnDestroy{this.subscription.unsubscribe;}數據綁定:讓你的應用程式活躍起來單向數據綁定:單向數據綁定是一種將數據從組件傳遞到模板的方式,但不允許模板對數據進行修改。這種綁定方式通常用於將組件中的數據呈現在用戶界面上,這樣用戶就可以查看相關數據。舉例來說,如果我們有一個顯示用戶名的變數,我們可以在模板中這樣使用:htmlp{{username}}/p雙向數據綁定:這是一個更強大的綁定方式,它不僅允許數據從組件傳遞到模板,還允許模板中的變更即時回傳到組件。這在處理表單元素等需要用戶輸入的情境中非常實用。例如,如果我們有一個用戶名的輸入框,我們可以使用ngModel]實現雙向綁定:htmlinputngModel]"username"現在,當用戶在輸入框中輸入用戶名時,username變數的值將自動更新,同時如果在組件中修改了username的值,輸入框中的內容也會同步更新。ps.需要在模塊中導入FormsModule,並在組件中引入FormsModule以使用雙向數據綁定。且需要確保模型屬性與模板中綁定的屬性名稱匹配,否則綁定將不起作用。使用插值表達式和屬性綁定將數據顯示在模板中在我們之前的範例中,我們已經看到了插值表達式的使用,它允許我們將組件中的變數值顯示在模板中。另一種方式是使用屬性綁定,它允許我們將組件的屬性值綁定到模板元素的屬性上。插值表達式:插值表達式使用雙花括號{{}}來包圍組件變數,將其值插入到模板中。這對於將數據呈現在HTML中非常方便。例如:htmlp{{message}}/p屬性綁定:屬性綁定使用方括號]來指定要綁定的HTML元素屬性,然後將組件的屬性值賦給它。這對於動態設置HTML元素的屬性非常有用。例如:htmlimgsrc]"imageUrl"另一個常見的用例是屬性綁定到元素的disabled屬性,這在按鈕等元素中非常有用:htmlbuttondisabled]"isDisabled"點擊/button在這個例子中,isDisabled變數的值決定了按鈕是否處於禁用狀態。當isDisabled為true時,按鈕將被禁用。事件處理:讓你的應用程式對用戶做出反應在Angular中,事件處理是實現與用戶互動的重要部分。你可以透過事件綁定來捕獲和處理各種用戶交互事件,例如點擊、輸入、滑鼠事件等。以下是更詳細的說明和範例:事件綁定:事件綁定允許你將模板中的事件(如點擊)與組件中的方法關聯起來,以便在事件發生時執行特定的操作。你可以使用括號來指定事件,並在括號內放入事件名稱,然後指定要調用的組件方法。舉例如下:htmlbuttonclick"onButtonClick"點擊我/buttontypescriptonButtonClick{this.fetchWeatherInfothis.city;}這樣,當用戶點擊按鈕時,onButtonClick方法將被觸發。事件對象:有時候,你可能需要獲取有關事件的更多信息,例如滑鼠事件的坐標或鍵盤事件的按鍵信息。你可以通過將$event傳遞給組件方法來獲取事件對象。舉例來說:htmlinputkeyup"onKeyUp$event"typescriptonKeyUpevent:KeyboardEvent{console.logevent.keyCode;}這樣,你可以獲取有關按鍵事件的詳細信息並做出相應的處理。設置路由以及子路由路由是指導航的基礎,它允許你在不同的視圖之間切換,就像在單頁應用程式中一樣。在Angular中,你可以使用RouterModule來設置路由。讓我們假設你正在建立一個簡單的博客應用程式,其中包含主頁、文章列表和文章詳細頁面。設置路由你需要在應用程式的根模塊中配置路由器:typescript//app.module.tsimport{NgModule}from"@angular/core";import{RouterModule,Routes}from"@angular/router";import{HomeComponent}from"./home.component";import{BlogListComponent}from"./bloglist.component";import{BlogSingleComponent}from"./blogsingle.component";constroutes:Routes{path:"",component:HomeComponent},{path:"blog",component:BlogListComponent},{path:"blog/:id",component:BlogSingleComponent},];@NgModule{imports:RouterModule.forRootroutes],exports:RouterModule],}exportclassAppModule{}在這個例子中,我們定義了三個路由:主頁、文章列表頁面blog和文章詳細頁面blog/:id。這些路由與相應的組件相關聯。接下來,你需要在應用程式的模板中添加一個routeroutlet/routeroutlet標記,這個標記將用來顯示不同路由下的內容:htmlnavarouterLink"/"主頁/aarouterLink"/blog"文章列表/a/navrouteroutlet/routeroutlet你已經設置了基本的路由結構。當用戶點擊頁面上的鏈接時,應用程式將根據路由的定義顯示相應的內容。設置子路由你可能希望在一個路由下設置子路由,來實現更複雜的導航結構。假設你的博客應用程式需要一個用於編輯文章的功能,你可以使用子路由來實現:typescriptconstroutes:Routes{path:"",component:HomeComponent},{path:"blog",component:BlogListComponent},{path:"blog/:id",component:BlogSingleComponent,children:{path:"edit",component:BlogEditComponent},],},];當用戶訪問articles/1/edit時,將顯示BlogEditComponent。路由守衛路由守衛允許你在導航到某個路由前執行一些操作。這對於驗證用戶、保護特定頁面或執行特定任務非常有用。在Angular中,有四種主要的路由守衛:CanActivate:檢查是否允許訪問某個路由。CanDeactivate:檢查是否允許離開某個路由。Resolve:在路由激活前解析數據。CanLoad:在懶加載模塊前檢查權限。假設你希望確保只有登入的用戶才能訪問編輯文章頁面:auth.service.tstypescriptimport{Injectable}from"@angular/core";@Injectable{providedIn:"root",}exportclassAuthService{privateisAuthenticated:booleanfalse;login{this.isAuthenticatedtrue;}logout{this.isAuthenticatedfalse;}isAuthenticatedUser:boolean{returnthis.isAuthenticated;}}在這個範例中,AuthService服務模擬了login、logout和isAuthenticatedUser身份驗證操作的方法。auth.guard.tstypescriptimport{Injectable}from"@angular/core";import{CanActivate,ActivatedRouteSnapshot,RouterStateSnapshot,UrlTree,Router}from"@angular/router";import{Observable}from"rxjs";import{AuthService}from"./auth.service";//導入AuthService@Injectable{providedIn:"root",}exportclassAuthGuardimplementsCanActivate{constructorprivateauthService:AuthService,privaterouter:Router{}canActivatenext:ActivatedRouteSnapshot,state:RouterStateSnapshot:Observableboolean|UrlTree|Promiseboolean|UrlTree|boolean|UrlTree{ifthis.authService.isAuthenticatedUser{returntrue;}else{//如果未登入,重定向到登入頁面this.router.navigate"/login"];returnfalse;}}}在這個範例中,AuthGuard檢查用戶是否已登入,如果已登入,則允許訪問路由,否則將用戶重定向到登入頁面。接下來,我們可以在路由配置中使用這個守衛。假設我們有一個需要身份驗證的私人頁面,我們可以這樣設置它:app.module.tstypescriptconstroutes:Routes{path:"articles/:id/edit",component:BlogEditComponent,canActivate:AuthGuard],},];當用戶訪問articles/1/edit頁面時,將首先觸發AuthGuard,並檢查是否允許訪問。懶加載懶加載是一種優化技術,它允許你將應用程式按需分割成多個模塊,以降低初始加載時間。在Angular中,你可以使用懒加载模塊來實現這一目標。先建立一個懒加載模塊:bloglist.module.tstypescript//import{NgModule}from"@angular/core";import{RouterModule,Routes}from"@angular/router";import{BlogListComponent}from"./bloglist.component";constroutes:Routes{path:"",component:BlogListComponent},];@NgModule{imports:RouterModule.forChildroutes],exports:RouterModule],}exportclassBlogListModule{}接著,在路由配置中使用canLoad守衛來實現懶加載:app.module.tstypescriptconstroutes:Routes{path:"blog",loadChildren:import"./bloglist.module".thenmm.BlogListModule,canLoad:AuthGuard],},];這將使BlogListModule在用戶首次訪問/blog頁面時才被加載。模板驅動表單vs.響應式表單模板驅動表單模板驅動表單是一種較簡單的方式來處理表單,它的主要思想是將表單的狀態和行為與模板相關聯。在這種方法中,你可以使用Angular模板語法來建立表單,然後通過模板變數來訪問和操作表單控件。以下是一個簡單的模板驅動登入表單:htmlformloginForm"ngForm"ngSubmit"onSubmit"labelfor"username"名稱:/labelinputtype"text"id"username"name"username"ngModel]"user.username"requiredlabelfor"password"密碼:/labelinputtype"password"id"password"name"password"ngModel]"user.password"requiredbuttontype"submit"登入/button/form在這個例子中,我們使用ngForm指令來建立表單,並使用ngModel]雙向數據綁定將表單控件與組件中的屬性關聯起來。當用戶提交表單時,我們呼叫onSubmit方法來處理表單數據。模板驅動表單的優勢在於簡單易上手,特別適用於簡單的表單。但對於複雜的表單,響應式表單可能更適合。響應式表單響應式表單是一種更強大和靈活的方式來處理表單。它使用RxJS庫來建立表單控件的可觀察對象,這些對象允許你更細粒度地控制表單的狀態和行為。以下是一個簡單的響應式登入表單範例:typescriptimport{Component}from"@angular/core";import{FormBuilder,FormGroup,Validators}from"@angular/forms";@Component{selector:"applogin",template:formformGroup]"loginForm"ngSubmit"onSubmit"labelfor"username"名稱:/labelinputtype"text"id"username"formControlName"username"labelfor"password"密碼:/labelinputtype"password"id"password"formControlName"password"buttontype"submit"登入/button/form,}exportclassLoginComponent{loginForm:FormGroup;constructorprivatefb:FormBuilder{this.loginFormfb.group{username:"",Validators.required],password:"",Validators.required],};}onSubmit{ifthis.loginForm.valid{//表單驗證通過,處理登入}}}在這個範例中,我們使用FormBuilder創建了一個包含驗證規則的FormGroup,並通過formControlName將表單控件綁定到模板中。當表單驗證通過時,我們執行登入操作。表單驗證與錯誤處理表單驗證是確保用戶輸入的數據符合預期的一個關鍵部分。不論你使用模板驅動表單還是響應式表單,Angular都提供了豐富的驗證機制來幫助你實現這一目標。假設用戶名和密碼字段都是必填的。在模板驅動表單中,你可以添加required屬性:htmlinputtype"text"id"username"name"username"ngModel]"user.username"requiredinputtype"password"id"password"name"password"ngModel]"user.password"required在響應式表單中,你則是這樣做:typescriptthis.loginFormfb.group{username:"",Validators.required]],password:"",Validators.required]],};當用戶未填寫必填字段時,Angular將自動顯示錯誤消息。你還可以自定義驗證器來滿足特定需求,例如驗證用戶名是否唯一或密碼是否符合一定的複雜性要求。在錯誤處理方面,Angular允許你輕鬆地檢測和處理表單中的錯誤。你可以通過以下方式檢測特定控件的錯誤:typescriptconstusernameControlthis.loginForm.get"username";ifusernameControl.hasError"required"{//用戶名是必填的,執行相應的處理}HTTP請求的使用、錯誤處理與測試送出HTTP請求Angular提供了HttpClient模組,用於發送HTTP請求。使用它,你可以輕鬆地執行GET、POST、PUT、DELETE等各種類型的請求。以下提供一個範例:typescriptimport{HttpClient}from"@angular/common/http";constructorprivatehttp:HttpClient{}getData{returnthis.http.get"/api/data";}postDatadata:any{returnthis.http.post"/api/data",data;}在這個範例中,我們定義了getData和postData方法,分別向後端發送GET和POST請求。處理HTTP錯誤在現實應用中,HTTP請求可能會遇到錯誤,例如服務器錯誤或網絡問題。為了提供更好的用戶體驗,我們需要妥善處理這些錯誤。typescriptgetData{returnthis.http.get"/api/data".pipecatchErrorerror:any{//在這裡處理錯誤,例如顯示錯誤消息或記錄錯誤returnthrowError"錯誤";};}在這個範例中,我們使用catchError來執行相應的處理。根據實際需求進行錯誤處理。測試HTTP請求測試是確保應用程式穩定性的關鍵部分。對於HTTP請求,你可以使用Angular的測試工具來撰寫單元測試和集成測試。假設我們有一個DataService需要測試:data.service.tstypescriptimport{Injectable}from"@angular/core";import{HttpClient}from"@angular/common/http";import{Observable}from"rxjs";@Injectable{providedIn:"root",}exportclassDataService{constructorprivatehttp:HttpClient{}getData:Observableany{returnthis.http.get"/api/data";}}接下來編寫一個單元測試,來測試DataService的getData。data.service.spec.tstypescriptimport{TestBed,inject}from"@angular/core/testing";import{HttpClientTestingModule,HttpTestingController}from"@angular/common/http/testing";import{DataService}from"./data.service";describe"DataService",{letservice:DataService;lethttpMock:HttpTestingController;beforeEach{TestBed.configureTestingModule{imports:HttpClientTestingModule],providers:DataService],};serviceTestBed.injectDataService;httpMockTestBed.injectHttpTestingController;};it"應該被建立",{expectservice.toBeTruthy;//確保service變數不是null或undefined};it"應該透過GET從API獲取數據",{consttestData{message:"這是一個測試"};service.getData.subscribedata{expectdata.toEqualtestData;//驗證數據是否如預期};constreqhttpMock.expectOne"/api/data";expectreq.request.method.toEqual"GET";//方法是GETreq.flushtestData;//模擬HTTP請求httpMock.verify;};afterEach{httpMock.verify;};};查看Angular的官方文檔和教程:Angular的官方文檔]https://angular.tw/guide/developerguideoverview是一個非常棒的學習資源,它包括了導覽、教程和詳細的API參考。通過閱讀文檔和完成官方教程,你可以快速地瞭解Angular的基本概念和使用方法。系列文章ahref"https://pardn.io/blog/frontendframeworkreact"target"self"React開發入門:打造動態前端的框架/a網頁前端新手必讀!Angular入門指南詳解ahref"https://pardn.io/blog/frontendframeworkvuejs"target"self"Vue.js入門指南:打造獨特且易於維護的前端界面/a三個框架與jQuery的比較,堅持不使用框架又會如何?:10/20相關連結作者:PardnChiu]https://github.com/pardnchiu輕量化框架:PDExtensionjs]https://github.com/pardnchiu/PDExtensionjsAngular的官方文檔:https://angular.tw/guide/developerguideoverview]https://angular.tw/guide/developerguideoverviewNode.js官方網站:https://nodejs.org/zhtw]https://nodejs.org/zhtw