《Angular4從入門到實戰》學習筆記css
騰訊課堂:米斯特吳 視頻講座html
二〇一九年二月十三日星期三14時14分前端
What Is Angular?(簡介)node
前端最流行的主流JavaScript框架; git
由谷歌傾情打造並維護;github
致力於構建單頁面應用(SPA);web
是主流MEAN綜合框架中的一部分;typescript
打破HTML靜態,建立動態的WEB應用。express
不是一個服務端的框架或技術;不是JS的一個庫,例如jQuery,React等;不是用於設計;不是一個平臺或一門語言;不是一個插件。(很是好)npm
Why Use Angular?(優勢)
能夠快速開發及代碼迭代;(相對於瀑布模型,就是開發過程用戶可見,先開發一個雛形,再迭代開發)
全部代碼都經過組件實現(模塊化)
動態獲取數據內容;
跨平臺
ECMAScript 6(如下簡稱ES6)是JavaScript語言的下一代標準,已經在2015年6月正式發佈了。
TypeScript:
是JavaScript的超集;微軟建立及維護;擁有具體的類型;面向對象;與JavaC#類似
Components(組件):
在Angular4中都是以組件式開發;在組件中包含選擇器,模板等;當前的類用戶處理邏輯。
安裝:AngularCLI(腳手架)或從github中拉取並使用
依賴的環境:NPM&NODE:也就是安裝node
從官網安裝並測試安裝成功否:node -v
因爲Angular CLI的一些資源被牆掉了,因此,要使用淘寶鏡像下載安裝,不然,慢且會主線問題。淘寶鏡像:https://npm.taobao.org/。
命令行輸入:npm install -g cnpm
再輸入:npm install -g cnpm --registry=https://registry.npm.taobao.org
安裝Angular Cli,命令行輸入:cnpm install -g @angular/cli@latest
檢驗是否安裝成功:ng help
Angular CLI的命令關鍵字爲:ng
建立項目:第一步ng new Test 出現綠色字體Ctrl+C終止批處理,由於很卡或出錯
第二步在項目文件夾輸入 cnpm install 從淘寶鏡像中安裝
而後用VScode(Visual Studio Code)打開項目或別的軟件打開。
官方網站指示:>npm install -g @angular/cli 換成cnpm install -g @angular/cli@latest
>ng new my-dream-app
>cd my-dream-app
>ng serve --open
持久使用:npm config set registry https://registry.npm.taobao.org
驗證是否成功:npm config get registry 或npm info express
使用:npm install -g cnpm --registry=https://registry.npm.taobao.org
二〇一九年二月十三日星期三23時37分
Angular項目的目錄結構:(網上摘錄)
組件相關的概念:
1.組件元數據裝飾器(@Component)
簡稱組件裝飾器,用來告知Angular框架如何處理一個TypeScript類.
Component裝飾器包含多個屬性,這些屬性的值叫作元數據,Angular會根據這些元數據的值來渲染組件並執行組件的邏輯
2.模板(Template)
咱們能夠經過組件自帶的模板來定義組件的外觀,模板以html的形式存在,告訴Angular如何來渲染組件,通常來講,模板看起來很像html,可是咱們能夠在模板中使用Angular的數據綁定語法,來呈現控制器中的數據。
3.控制器(controller)
控制器就是一個普通的typescript類,他會被@Component來裝飾,控制器會包含組件全部的屬性和方法,絕大多數的業務邏輯都是寫在控制器裏的。控制器經過數據綁定與模板來通信,模板展示控制器的數據,控制器處理模板上發生的事件。
裝飾器,模板和控制器是組件的必備要素。還有一些可選的元素,好比:
輸入屬性(@inputs):是用來接收外部傳入的數據的,Angular的程序結構就是一個組件樹,輸入屬性容許在組件樹種傳遞數據 。提供器(providers):這個是用來作依賴注入的 。生命週期鉤子(LifeCycle Hooks):一個組件從建立到銷燬的過程當中會有多個鉤子會被觸發,相似於Android中的Activity的生命週期 。樣式表:組件能夠關聯一些樣式表 。動畫(Animations): Angular提供了一個動畫包來幫助咱們方便的建立一些跟組件相關的動畫效果,好比淡入淡出等 。輸出屬性(@Outputs):用來定義一些其餘組件可能須要的事件或者用來在組件之間共享數據
下面咱們來看看模塊文件
app.module.ts:這個文件表示模塊
與AppComponent相似,模塊也須要裝飾器來裝飾。
二〇一九年二月十四日星期四0時3分
騰訊課堂:米斯特吳 《Angular4從入門到實戰》之第三講《Angular4建立組件及設置屬性》
運行剛剛建立的Angular項目,命令行進入到Angular\a4app項目目錄,輸入ng serve --open
或推送出要顯示的網頁,或者在瀏覽器地址欄輸入:http://localhost:4200/
感受就是一個web網站在運行,更改index.html等相關文件內容,只要按保存都會自動觸發瀏覽器更新。
項目執行的第一個文件就是項目目錄a4app下src目錄裏面的index.html文件。
在index.html中是沒法直接引入自定義的或其餘的CSS文件的,必須把CSS文件引入到src目錄中的styles.css文件中,此文件自己還能夠定義樣式(此文件一開始除了一行註釋之外是空的)。如:@charset "UTF-8";@import "test.css";
感受src目錄下的app目錄裏面的這五個文件都挺重要的,尤爲是這個app.component.ts,裏面的title內容一變,網頁上的標題當即跟着改變。
app.component.ts文件的內容:
import { Component } from '@angular/core';
@Component({
selector: 'app-root', /*表示該組件將展現在index.html中的<app-root>標籤中*/
templateUrl: './app.component.html', /*聲明該組件所應用的模板*/
styleUrls: ['./app.component.css'] /*聲明模板所應用的渲染*/
})
export class AppComponent {
title = 'Hello 世界!';
}
只要是組件,都會在app目錄下建立!
引用組件:先打開a4app中的readme.md,拷貝第11行的`ng generate component component-name`
再開起來一個終端(由於原來的終端正在運行WEB服務),目錄切換到項目目錄a4app下,輸入剛剛拷貝的命令行:ng generate component 組件名; 也能夠用簡寫的模式ng g c 組件名。
好比新建一個存放組件的文件夾及新建組件:ng g c components/user
因而:在app文件夾下新建了一個components目錄,components目錄又建了一個user目錄,
user目錄下面新建了四個文件,分別是組件css、html、ts、spec.ts其spec.ts用於測試的,沒用
咱們在根組件app的html文件中加入<app-user></app-user>
(由於user的ts文件指定的選擇器就是app-user,這與index中設置標籤< app-root >一模一樣)
而後,就能夠修改user下的html文件的內容和設置ts文件的對應的屬性了。
user目錄下的app.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {
name = "hemiah"; /*添加屬性*/
constructor() { } /*自動建立了兩個空的方法*/
ngOnInit() { }
}
好比添加了一個name屬性。而後,咱們就能夠在html中用{{name}}來調用這個name屬性的值。
user目錄下的app.component.ts還能夠這樣寫:
二〇一九年二月十四日星期四2時33分53秒
騰訊課堂:米斯特吳 《Angular4從入門到實戰》之第四講《Angular4操做數據(增刪改查)》
user.component.html文件實例:
<h1>Hello {{name}}!</h1>
<!--數據綁定-->
<ul>
<li>年齡:{{age}}</li>
<li>郵箱:{{email}}</li>
<li>地址:{{address.city}}{{address.state}}{{address.street}}</li>
</ul>
<!--ngFor循環-->
<ul>
<li *ngFor="let hobby of hobbies;let i='index'">
{{i+1}}:{{hobby}} <!-- 好神奇-->
<button (click)="deleteHobby(i)">X</button>
</li>
</ul>
<!--事件-->
<button (click)="onClick()">點我</button>
<!--表單-->
<form (submit)="addHobby(hobby.value)">
<div>
<label for="hobby">愛好:</label>
<input type="text" #hobby> <!-- #號是必須的,名字能夠自由起-->
</div>
</form>
<hr>
<button (click)="toggleEdit()">是否編輯用信息</button>
<!--編輯表單-->
<div *ngIf="isEdit"> <!--控制div組件是否可見-->
<h1>編輯用戶信息</h1>
<form>
<div>
<label for="name">姓名:</label>
<input type="text" [(ngModel)]="name" name="name"> <!--雙向數據綁定實現編輯功能-->
<!--使用ngModel必需要在app下的app.module.ts文件中引入
import { FormsModule} from '@angular/forms';
還要在此文的imports:[]中添加上:FormsModule 注:Angular2是自動添加的-->
</div>
<div>
<label for="age">年齡:</label>
<input type="text" [(ngModel)]="age" name="age">
</div>
<div>
<label for="city">城市:</label>
<input type="text" [(ngModel)]="address.city" name="city">
</div>
</form>
</div>
user.component.ts文件實例:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit { /*最外層 包括此行以上,由系統自動生成*/
/*先定義屬性*/
name: string;
age: number;
email: string;
address: Address;
hobbies: string[];
hello: any;
isEdit:boolean = false;
constructor() { /*在函數中注入依賴就能夠做爲類的屬性被使用了*/
console.log("constructor ran ...");
}
ngOnInit() { /*此方法內給屬性賦值,系統生成的空函數*/
console.log("ngOnInit ran ...");
this.name = "Hemiah";
this.age = 30;
this.email = "test@test.com";
this.address = {
street: "定泗路",
city: "北京",
state: "昌平區"
};
this.hobbies = ["寫代碼", "看電影", "聽音樂"];
}
/*再定義方法*/
onClick() {
// console.log(123);
this.name = "Mr.Wu";
this.hobbies.push("New Hobby"); /*push追加到後面*/
}
addHobby(hobby){
// console.log(hobby);
this.hobbies.unshift(hobby); /* unshift插入到前面*/
return false;
}
deleteHobby(i){
this.hobbies.splice(i,1); /*splice刪除,從下標開始1個項目*/
}
toggleEdit(){
this.isEdit= !this.isEdit;
}
} /*最外層*/
interface Address{ /*外層之外自定義數據類型*/
street:string,
city:string,
state:string
}
大體捋了一下執行過程:
一、 系統最早執行index.html,遇到其中的<app-root></app-root>標籤則去執行
二、 app.component.ts文件聲明的選擇器selector:app-root。此文檔的兩個語句分別指向了兩個文件
styleUrls: ['./app.component.css'];templateUrl: './app.component.html',
三、 執行./app.component.html,引出文件中的<app-user></app-user>標籤,而後去執行
四、 user.component.ts文件中生命的選擇器:selector:app-user。此文檔包含兩個語句:
styleUrls: ['./user.component.css'];templateUrl: './user.component.html',
五、最後執行:./user.component.html
ts文件相似於JavaScript文件,不過,困惑的是,爲何html文件中沒有引用語句呢?
二〇一九年二月十四日星期四5時32分43秒
二〇一九年二月十四日星期四12時10分29秒
騰訊課堂:米斯特吳 《Angular4從入門到實戰》之第五講《Angular4核心功能Service》
What Is Service?
服務主要應用於多個組件中的數據管理;
可讓組件更乾淨;
DRY—Don't Repeat Yourself;
經過HTTP Module對數據進行增刪改查。
建立服務的步驟:
建立一個新文件 /services/my-service.service.ts
import@Injectable而且建立class;
引入Service並添加到procide中;
任何組件須要使用須要引入並建立對象調用。
也使用命令建立Service:
ng g service services/my-service
會自動幫助咱們建立文件以及寫入對應的class
咱們須要手動將Service添加到procider中
二〇一九年二月十四日星期四22時29分
騰訊課堂:米斯特吳 《Angular4從入門到實戰》之第六講《Angular4建立及使用Service》
Angular>a4app> ng g c components/home 建立一個新組件
ng serve --open 啓動web服務
修改app.component.html 把標籤換成:<app-home></app-home>指向新組件
在app目錄下手動建立一個目錄services,在目錄中手動建立一個文件data.service.ts
手動添加初步代碼以下:
import {Injectable} from '@angular/core'; /*引入Injectable*/
@Injectable() /*調用Injectable*/
export class DataService{ /*導出數據*/
users:string[];
constructor(){
this.users=["米斯特吳","Ac總有一天","吳海洋"]
}
getUsers(){
return this.users; /*準備給home.component.html返回數據*/
}
}
準備把data.service.ts中的數據返回給home.component.html
首先要在app.module.ts中要引入 import { DataService} from './services/data.service';
並放入此文件的提供器中:providers:[DataService], 這一行代碼很重要!
接下來就可使用了,好比在home.componet.ts中,先引入這個服務:
import { DataService} from '../../services/data.service';
而後改造已有的空構造函數constructor(){}以下:
users:string[];
constructor(public dataService:DataService) {
// console.log(this.dataService.getUsers());
this.users=this.dataService.getUsers();
}
而後就能夠在home.componet.html中拿到home.componet.ts中的數據了!
<h1>Hello World!</h1>
<ul>
<li *ngFor="let user of users">
{{user}}
</li>
</ul>
這就是數據引入的全過程!
好比,在user組件中引入,第一步,在user.componet.ts中引入
import { DataService} from '../../services/data.service';
第二步:在constructor也建立好:constructor(public dataService:DataService){}
而後,返回home.componet.ts定義一個數組:users:string[];
而後再回到user.componet.ts中定義一個數組以下:
users:string[];
constructor(public dataService:DataService) {
this.users=this.dataService.getUsers();
}
其實就是改造user.componet.ts文件,添加引入,定義構造函數引入,而後引入!
接下在在user.componet.html中加入home.componet.html中的相似語句的數據引用,數據就順利的引入到了user.componet.html中來了。
最後,最後,來到app.componet.html中,經過修改標籤<app-user></app-user>或是<app-home></app-home>就能夠重定向選擇器,來拿取不一樣的數據了。這樣就達到數據統一管理的目的!!!!!
接下來的例子user是不用的,這裏僅僅是演示數據的管理的便利性。
在html中引入一些好看的樣式:
www.bootswatch.com
點擊Cosmo的DOWNLOAD
出現頁面:https://bootswatch.com/4/cosmo/bootstrap.min.css,拿到CDN(內容分發網絡)也就是這個網址名字。
而後,在index.html中引入:
<link rel="stylesheet" href="https://bootswatch.com/4/cosmo/bootstrap.min.css">
而後修改html加上指定的class名,就起到了渲染的目的了:
<h1>Hello World!</h1>
<ul class="list-group">
<li class="list-group-item" *ngFor="let user of users">
{{user}}
</li>
</ul>
2/15/2019 1:03:35 AM
二〇一九年二月十五日星期五1時4分33秒
騰訊課堂:米斯特吳 《Angular4從入門到實戰》之第七講《Angular4 ES7中的觀察者對象Observable》
ES7不隸屬於Angular但後面的知識要用到它:
首先在data.service.ts中引入Observable: import {Observable} from 'rxjs';
而後定義一個新的數據類型:data:Observable<Array<number>>;而後修改getUsers(){}
getUsers(){
// return this.users; /*準備給home.component.html返回數據*/
this.data = new Observable(observer=>{
//讓咱們當前的data,等於新建立起來的Observable對象,對象裏面會有對應的
//給咱們傳輸的數據,括號裏面的是回調函數,咱們用箭頭函數,在箭頭函數中,
//咱們想讓它每隔1秒傳輸對應的數據,而後在咱們的頁面展現出來實時獲取到的數據
//咱們傳的數據就至關於咱們get請求的數據
setTimeout(()=>{ /*咱們一樣用回調函數*/
observer.next(1);
},1000);
setTimeout(()=>{
observer.next(2);
},2000);
setTimeout(()=>{
observer.next(3);
},3000);
setTimeout(()=>{
observer.next(4);
},4000);
setTimeout(()=>{
observer.complete();
},5000);
});
return this.data; /*這是很是關鍵的一個語句,用於返回數據 */
}
而後,在home.component.ts中引用數據:
data:any[]=[]; /*定義一個空數組*/
constructor(public dataService:DataService) {
// console.log(this.dataService.getUsers());
// this.users=this.dataService.getUsers();
//Observable
this.dataService.getUsers().subscribe(data=>{ /*用訂閱者模式拿到數據*/
// console.log(data);
this.data.push(data); /*把data push進來*/
})
}
最後經過home.componet.html達到最終引用到頁面之目的:(ts只能引用到控制檯層面)
<h1>Hello World!</h1>
<ul class="list-group">
<li class="list-group-item" *ngFor="let d of data">
{{d}}
</li>
</ul>
這就是ES7中的Observable之後要用到的。 2/15/2019 2:45:13 AM
二〇一九年二月十五日星期五2時46分18秒
騰訊課堂:米斯特吳 《Angular4從入門到實戰》之第八講《Angular4使用Http中Get獲取網絡接口數據》
第一步:
在app.module.ts引入一個get請求:
Angular 4.3 版本後,推薦使用 HttpClient,能夠參考 Angular HTTP Client 快速入門
因此,把import { HttpModule} from '@angular/http';
改成:import { HttpClientModule} from '@angular/common/http';
而後,在imports:[]中再引入一下:HttpClientModule
第二步:
在services中使用HTTP,打開:data.service.ts:先把把有關Observable的有關內容清除
而後引入HTTP:(視頻中的老版本在我這新版本上還真的出問題,乾脆百度一下,一次解決)
引入的命令爲:import { HttpClient} from '@angular/common/http';
(視頻中的爲:import { Http} from '@angular/http';)
而後用constructor建立對象http(名字任意起),之後用這個對象來調用get,pot,post,delet等:
constructor(public http:Http){ }
而後:咱們把請求的數據在getUsers(){}中return回去,get中就能夠放請求數據的接口:
(模擬數據接口:打開網站http://jsonplaceholder.typicode.com/請求Resources的users)
return this.http.get("http://jsonplaceholder.typicode.com/users ")
返回數據時,實際上是返回的觀察者對象Observable要用到map方法,因爲不能直接調用,因此,必須在文件頭引入:import 'rxjs/add/operator/map'; 這一句總是報錯!!!!!!取消就不會報錯!
而後再getUsers(){}中加入.map(res=>res.json()); 這句也報錯!!!只好也取消!
好像這兩行取消了,後臺依然可以抓取到網頁的數據,是否是Angular新版本已經用HttpClient把這兩個功能實現了呀?
接下來:在home.component.ts
constructor(public dataService:DataService) {
this.dataService.getUsers().subscribe(users=>{ /*觀察者對象下的訂閱者模式*/
console.log(users); 觀察控制檯的數據輸出否?
})
}
若是數據輸出正確,則註釋掉控制檯輸出,添加以下代碼:
constructor(以前):users:any[];
constructor中添加:this.users = users; 把訂閱者模式抓取到的數據users賦給了本組件聲明的數組users[]裏面來了。users數組因而就有了數據,html就可使用他們了。
最後,在home.component.html中添加:
<h1>Hello World!</h1>
<div *ngFor="let user of users">
<div class="well"> <!--由於在index.html已經引入了CSS模板-->
<ul class="list-group">
<li class="list-group-item">姓名:{{user.name}}</li>
<li class="list-group-item">郵箱:{{user.email}}</li>
<li class="list-group-item">電話:{{user.phone}}</li>
</ul>
</div>
</div>
這節課學得最費勁,由於搭建的版本與視頻例題不一致,不知因此雲,百度和思考花費了一些時間。
2/15/2019 6:08:21 AM
繼續上面的app.module.ts出錯處理:
好像還不行,改爲這樣就經過了,但就是pipe()這麼寫,我本身都不知道是啥意思!
import { map} from 'rxjs/operators';
.pipe(map(res => res));
下面這篇文章感受挺權威了:
《從Angular 4開始,Angular的http請求改用HttpClient。》
添加HttpClientModule
首先須要引入HttpClientModule,它須要放在BrowserModule後:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [
BrowserModule,
HttpClientModule,
],
declarations: [
AppComponent,
],
bootstrap: [ AppComponent ]
})
export class AppModule {}
請求JSON數據
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable()
export class ConfigService {
constructor(private http: HttpClient) { }
getData() {
return this.http.get(this.dataUrl);
}
}
HttpClient其中一個特性是默認返回的數據爲json數據。,使用它返回的數據以下:
http.get(url).subscribe(...)
對於angular 4以前,則須要作json轉換:
http.get(url).map(res => res.json()).subscribe(...)
請求非JSON數據
若是須要返回非JSON數據,則須要在請求時設置responseType頭信息爲text:
getTextFile(filename: string) {
return this.http.get(filename, {responseType: 'text'})
.pipe(
tap(
data => this.log(filename, data),
error => this.logError(filename, error)
)
);
}
http.get()返回的是一個Observable<String>
2/15/2019 6:42:47 AM
結論是:在data.service.ts中的這兩句沒有必要添加了,由於HttpClient其中一個特性是默認返回的數據爲json數據,從Angular4.X之後的版本,就不在須要以下設置啦:
import { Http} from '@angular/http';
.map(res=>res.json());
二〇一九年二月十五日星期五15時20分
騰訊課堂:米斯特吳 《Angular4從入門到實戰》之第九講《Angular4使用Http中的Post傳遞數據》
先註釋掉user中ts和html中的Observable,其實已經註釋掉了,只是標註Observable註釋標記而已
接下來開始操做home.component.html文件了......
<h1>Hello World!</h1>
<div class="container">
<form (submit)="onSubmit()"> <!--添加一個form和提交觸發事件-->
<div class="form-group">
<label>姓名</label>
<input type="text" class="form-control" [(ngModel)]="user.name" name="name">
</div>
<div class="form-group">
<label>郵箱</label>
<input type="text" class="form-control" [(ngModel)]="user.email" name="email">
</div>
<div class="form-group">
<label>電話</label>
<input type="text" class="form-control" [(ngModel)]="user.phone" name="phone">
</div>
<input type="submit" class="btn btn-success" value="提交">
</form>
<hr>
<div *ngFor="let user of users">
<div class="well"> <!--由於在index.html已經引入了CSS模板-->
<ul class="list-group">
<li class="list-group-item">姓名:{{user.name}}</li>
<li class="list-group-item">郵箱:{{user.email}}</li>
<li class="list-group-item">電話:{{user.phone}}</li>
</ul>
</div>
</div>
</div>而後在home.component.ts中設計user對象並實現html中定義的onSubmit方法並自定義addUser()方法:
export class HomeComponent implements OnInit {
users:any[];
user = {
name:"",
email:"",
phone:""
}
constructor(public dataService:DataService) {
this.dataService.getUsers().subscribe(users=>{ /*觀察者對象下的訂閱者模式*/
// console.log(users); /*觀察控制檯數據是否正確輸出*/
this.users = users;
})
}
onSubmit(){
this.dataService.addUser(this.user).subscribe(user=>{
// console.log(user); /*查看控制檯輸出*/
this.users.unshift(user); /*直接顯示在html頁面中*/
})
}
而後在data.service.ts中實現addUser這個方法:再也不.map(res=>res.json())
addUser(user){
return this.http.post("http://jsonplaceholder.typicode.com/users",user)
}
2/15/2019 4:29:31 PM16:29:08
二〇一九年二月十五日星期五16時30分
騰訊課堂:米斯特吳 《Angular4從入門到實戰》之第十講《Angular4使用Http中的Delete刪除數據》
在home.component.html中的ul標籤後添加刪除按鈕
<button (click)="onDeleteClick(user.id)" class="btn btn-danger">刪除</button>
而後在ts裏面home.component.ts來實現onDeleteClick()方法:
onDeleteClick(id){
// console.log(id);
this.dataService.deleteUser(id).subscribe(res=>{
})
}
自定義一個方法deleteUser(id)。
而後,再在data.service.ts中實現這個deleteUser(id)方法:
deleteUser(id){
return this.http.delete("http://jsonplaceholder.typicode.com/users/"+id)
}
而後在ts裏面home.component.ts來進一步實現onDeleteClick()方法的刪除動做:
而後在ts裏面home.component.ts來實現onDeleteClick()方法:
onDeleteClick(id){
// console.log(id);
this.dataService.deleteUser(id).subscribe(res=>{
for(let i=0;i<this.users.length;i++){
if(this.users[i].id==id){
this.users.splice(i,1);
}
}
})
}
這樣就測試成功了。刪除就能夠操做了。不過,刷新頁面,刪除的數據又回來來了,是由於網站提供的數據是測試數據,不能被真正的刪除。
2/15/2019 5:50:48 PM
二〇一九年二月十五日星期五19時48分
騰訊課堂:米斯特吳 《Angular4從入門到實戰》之第11講《Angular4使用Http中的put更新數據》
先在hpme.component.html添加編輯按鈕:
<button (click)="onEditClick(user)" class="btn btn-danger">編輯</button>
第二步:在home.component.ts定義onEditClick()這個按鈕:
因爲編輯要與輸入共用一個框,因此,要先定義:
isEdit:boolean=false;
而後:
onEditClick(user){
this.isEdit=true;
this.user=user; /*先把值傳到輸入框(編輯框)內*/
}
把onSubmit()賦參數:onSubmit(isEdit) 以接收其值,定義了一個新的方法updataUser(this.user)。
onSubmit(isEdit){
if (isEdit){ /*若是isEdit=true則執行put方法進行編輯編輯*/
this.dataService.updataUser(this.user).subscribe(user=>{
//刪除當前的
for(let i=0;i<this.users.length;i++){
if(this.users[i].id==this.user.id){
this.users.splice(i,1);
}
}
//添加更新的
this.users.unshift(this.user);
})
} else { /*若是isEdit=fales則執行post方法*/
this.dataService.addUser(this.user).subscribe(user=>{
// console.log(user); /*查看控制檯輸出*/
this.users.unshift(user); /*直接顯示在html頁面中*/
})
}
}
把html中的form作相應修改:<form (submit)="onSubmit(isEdit)">
若是isEdit傳過來的是false,則執行post;若是是true則執行put(編輯)!
爲了讓home.component.ts中心的方法updataUser(this.user)起做用,要在data.service.ts中進行設定:
updataUser(user){
return this.http.put("http://jsonplaceholder.typicode.com/users/"+user.id,user)
}
2/15/2019 9:07:15 PM
二〇一九年二月十五日星期五21時11分
騰訊課堂:米斯特吳 《Angular4從入門到實戰》之第12講《Angular4核心模塊Router》
路由就是解決從一個視圖到另外一個視圖的導航,也就是不通過網絡請求,刷新頁面的狀況下跳轉到另外一個頁面。速度很是快。
路由的基本步驟:
<base href>在index.html
引入路由模塊
建立路由
設置路由出口
添加路由連接
首先在index.html中設置根路徑:<base href="/">
導入路由模塊:import { RouterModule,Routes } from '@angular/router';
添加路由模塊:imports:[
BrowserModule,
RouterModule.forRoot(appRoutes)
],
建立路由:
const appRoutes:Routes = [
{ path: '',component:HomeComponent },
{ path: 'about',component:AboutComponent },
{ path: '**',component:pageNotFoundComponent }
];
建立路由連接:<a class="nav-link" href="#" routerLink="/">Home</a>
添加組件出口:<router-outlet></router-outlet>
第一步:先檢視一下index.html中是否已經有了<base href="/">
第二步:到app.module.ts中添加路由模塊:
import { RouterModule,Routes } from '@angular/router';
並把路由模塊用一下:
imports:[
BrowserModule,
RouterModule.forRoot(appRoutes) 用forRoot來執行一下下面建立的路由appRoutes
],
並設置一個路由:
const appRoutes:Routes = [
{ path: '',component:HomeComponent },
{ path: 'user',component:UsertComponent }
];
第三步:在app.component.html中把<app-home></app-home>註釋掉,而後添加一個出口:
<router-outlet></router-outlet>
這是,在地址欄輸入:http://localhost:4200
將顯示不一樣的網頁。
不過,這個路由還不夠智能,須要繼續下面的步驟:
建立一個導航的組件:
在控制檯,切換到D:\Angular\a4app>執行:ng g c components/navbar
PS D:\Angular\a4app> ng g c components/navbar
CREATE src/app/components/navbar/navbar.component.html (25 bytes)
CREATE src/app/components/navbar/navbar.component.spec.ts (628 bytes)
CREATE src/app/components/navbar/navbar.component.ts (269 bytes)
CREATE src/app/components/navbar/navbar.component.css (0 bytes)
UPDATE src/app/app.module.ts (985 bytes)
PS D:\Angular\a4app>
新建的navbar自動更新到了app.module.ts中去了,也就是,多了一條語句:
import { NavbarComponent } from './components/navbar/navbar.component';
@NgModule中的declarationts:[]也引入了一行:NavbarComponent
而後在navbar.component.html添加導航,爲了便捷,到bootstrap網站抓一個導航過來:
百度bootstrap中文網www.bootcss.com àBootstrap3中文文檔(v3.3.7)
à下載Bootstrapà點擊右側導航「實例精選」à點擊Bootstrap框架的基本用法下面左側窗口
à出現Bootstrap starter template頁面後à右鍵查看源碼,或Ctrl-U查看源碼,或省去前面的全部步驟,直接在地址欄輸入:view-source:https://v3.bootcss.com/examples/starter-template/ 查看源碼,把導航的這部分拷貝到navbar.component.html中:
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
改形成:
<nav class="navbar navbar-light">
<div class="container">
<a class="navbar-brand" href="#">Angular4</a>
<div id="navbar" class="navbar-collapse">
<ul class="nav navbar-nav">
<li><a href="#" routerLink="/">Home</a></li>
<li><a href="#" routerLink="/user">User</a></li>
</ul>
</div>
</div>
</nav>
而後,咱們在app.component.html中調用這個導航:
<app-navbar></app-navbar>
2/15/2019 11:56:14 PM(ul li的顯示樣式始終沒搞明白!)
二〇一九年二月十六日星期六0時8分
騰訊課堂:米斯特吳 《Angular4從入門到實戰》之第13講《公益廣告》
騰訊課堂:米斯特吳 《Angular4從入門到實戰》之第14講《Angular4核心模塊Router參數》
路由參數就是在訪問的網址上加上不一樣的參數而跳轉到不一樣的頁面。
第一步:再到a4app建立一個新組件:ng g c components/userDetail
第二步:在app.module.ts裏除了自動更新的引入新組件,還要寫路由參數:
const appRoutes:Routes = [
{ path: '',component:HomeComponent},
{ path: 'user',component:UserComponent},
{ path: 'user/:id',component:UserDetailComponent},
];
第三步:到user-detail.component.ts中獲取路由參數:
import { Router,ActivatedRoute,Params} from '@angular/router';
並在contructor(){}作相關的定義:
constructor(
private route:ActivatedRoute,
private router:Router
) {
this.route.params.subscribe((params:Params)=>{
console.log(params.id);
})
}
到瀏覽器地址欄輸入:http://localhost:4200/user/1,就可跳轉到user-detail work!中,說明鏈接成功
接下來繼續設置:
打開home.component.html設置a標籤
<a class="btn btn-primary pull-right" [(routerLink)]="'/user/'+user.id">詳情</a>
接下來根據咱們的ID,請求其所對應的數據:在user-detail.component.ts
id:number;
this.route.params.subscribe((params:Params)=>{
// console.log(params.id);
this.id=params.id;
})
}
再把服務引進來:
import {DataService} from '../../services/data.service';
因而咱們就能夠在data.service.ts中的添加方法:
getSingleUser(id){
return this.http.get("http://jsonplaceholder.typicode.com/users/"+id)
}
接下來,在user-detail.component.ts調用這個方法:
public dataServicde:DataService,
ngOnInit() {
this.dataServicde.getSingleUser(this.id).subscribe((user)=>{
console.log(user);
})
}
再添加:user:object={};
最後,咱們就能夠在user-detail.component.html中實現這個代碼:
<h1>用戶詳情</h1>
<ul class="list-group">
<li class="list-group-item">{{user.id}}</li>
<li class="list-group-item">{{user.name}}</li>
<li class="list-group-item">{{user.email}}</li>
<li class="list-group-item">{{user.phone}}</li>
<li class="list-group-item">{{user.website}}</li>
</ul>
順利經過!
user-detail.component.ts完整代碼:
import { Component, OnInit } from '@angular/core';
import { Router,ActivatedRoute,Params} from '@angular/router';
import {DataService} from '../../services/data.service';
@Component({
selector: 'app-user-detail',
templateUrl: './user-detail.component.html',
styleUrls: ['./user-detail.component.css']
})
export class UserDetailComponent implements OnInit {
id:number;
user:object={};
constructor(
public dataServicde:DataService,
private route:ActivatedRoute,
private router:Router
) {
this.route.params.subscribe((params:Params)=>{
// console.log(params.id);
this.id=params.id;
})
}
ngOnInit() {
this.dataServicde.getSingleUser(this.id).subscribe((user)=>{
// console.log(user);
this.user=user;
})
}
}
data.service.ts完整代碼:
import {Injectable} from '@angular/core'; /*引入Injectable*/
import { HttpClient} from '@angular/common/http';
// import 'rxjs/add/operator/map'; HttpClient返回的就是json數據了,因此這個引入廢棄了
@Injectable() /*調用Injectable*/
export class DataService{
constructor(public http:HttpClient){ /*建立對象http以此調用get、post等*/
}
getSingleUser(id){
return this.http.get("http://jsonplaceholder.typicode.com/users/"+id)
}
getUsers(){
return this.http.get("http://jsonplaceholder.typicode.com/users")
// .map(res => res.json()); HttpClient返回的就是json數據了,因此再也不須要轉換了
}
addUser(user){
return this.http.post("http://jsonplaceholder.typicode.com/users",user)
}
deleteUser(id){
return this.http.delete("http://jsonplaceholder.typicode.com/users/"+id)
}
updataUser(user){
return this.http.put("http://jsonplaceholder.typicode.com/users/"+user.id,user)
}
}
app.module.ts完整代碼:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule} from '@angular/forms';
import { HttpClientModule} from '@angular/common/http';
import { RouterModule,Routes} from '@angular/router';
import { AppComponent } from './app.component';
import { UserComponent } from './components/user/user.component';
import { HomeComponent } from './components/home/home.component';
import { DataService} from './services/data.service';
import { NavbarComponent } from './components/navbar/navbar.component';
import { UserDetailComponent } from './components/user-detail/user-detail.component';
const appRoutes:Routes = [
{ path: '',component:HomeComponent},
{ path: 'user',component:UserComponent},
{ path: 'user/:id',component:UserDetailComponent},
];
@NgModule({
declarations: [
AppComponent,
UserComponent,
HomeComponent,
NavbarComponent,
UserDetailComponent
],
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
RouterModule.forRoot(appRoutes)
],
providers: [DataService],
bootstrap: [AppComponent]
})
export class AppModule { }
本視頻課程基本完結了,後面還有一個具體的代碼
2/16/2019 1:24:23 AM
二〇一九年二月十六日星期六1時25分27秒總用時兩天半 要熟練還得具體項目磨鍊