花一些時間來撰寫包版筆記,因為中間遇到太多問題,折騰了不少時間呀...
首先,來實作 Angular2 部署到IIS 的部分
Step 1. 使用CMD 到專案根目錄,輸入下面這段,即可將 TypeScript 編譯成 .js 檔
ng build -prod
編譯完成後,在專案的根目錄會出現一個 dist 資料夾,內容如下:
Step 2. 將整個資料夾搬到 IIS 目錄下,並設定IIS
1) 右鍵點選站台 >> 新增網站
2) 站台名稱:輸入站台名稱
3) 實體路徑:選擇剛剛編譯的 dist 資料夾
4) 按下確定即完成部署
作到這個步驟已經完成了 Angular2 的部署了,但如果你有使用到 WebAPI 的話,必須要將WebAPI 與網站部署在一起,否則會有 Failed to load resource: the server responded with a status of 404 (Not Found) 這樣的錯誤出現。接著開始部署 WebAPI 的部分
Step 1. 在IIS 點選剛剛部署好的站台名稱,按右鍵選則新增應用程式
1) 別名:輸入WebAPI名稱
(這個名稱必須要跟Angular2所呼叫的路徑相同,例如前端呼叫的路徑是http://localhost/KyleAPI/api/values,其中KyleAPI就是應用程式的別名,而 api 是預設的route 路徑,values 就是 controller)
2) 實體路徑:選擇 WebAPI 編譯好的資料夾位子
3) 按下確定即完成
最後,部署完的結構如下:
Step 2. 之後,可以在 vs2012 直接發行來更新WebAPI,設定如下:
1) 右鍵點選方案總管的專案名稱,選擇發佈
2) 新增設定檔,並給予一個設定檔的名稱
3) 服務URL:輸入伺服器的IP
4) 網站/發行:輸入IIS部屬的位置,如上例為 test/KyleAPI
5) 使用者名稱/密碼:伺服器的帳密
6) 按下驗證連線,檢查是否連線成功
7) 如果沒有問題,之後即可直接透過發行來進行 WebAPI更新
上面已完成 Angular2 與 C# WebAPI 一同部署到 IIS 上,但實際上,我們還會遇到一些不預期的錯誤。
Issue 1. 因為小太陽的公司裡有些電腦不可以連外網,只能連結內部網路,有些需靠網路的 css 與 js 會有找不到的狀況。如下為 chrome console 所顯示的錯誤訊息:
http://10.56.xxx.xxx/assets/css/bootstrap-theme.min.css.map 404 (Not Found)
http://10.56.xxx.xxx/assets/css/bootstrap.min.css.map 404 (Not Found)
檢查了一下Angular2 根目錄的 index.html,發現有些 css 是直接透過外部網路連結
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="http://netdna.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
解法就是將這些 css 與 js 抓回來,放到 \src\assets\css 與 \src\assets\js 裡面,並更改連結位置,再進行 ng build ,這時我們的 css 與 js 檔都是由 assets 所提供,就算不能連外網也可以正常瀏覽了。
Issue 2. 出現「Uncaught TypeError: Cannot read property 'apply' of undefined」的錯誤,這個錯誤折騰了小太陽很久,因為在網路上找到的討論串,只要將 zone.js 降版到 0.8.5、@angular/core 版本為 4.0.3 就不會出現這樣的錯誤,打開CMD 到專案根目錄輸入下面這兩段,就可以將 zone.js 與 angular/core 安裝為指定版本(連 package.json 也會一併更改)
npm install @angular/core@4.0.3 --save
npm install zone.js@0.8.5 --save
但是在公司裡還是有一些電腦會出現錯誤,後來才想到會不會是瀏覽器版本的問題,原來,公司舊電腦 xp/2003 等,所安裝的 chrome 版本是 38.0 版,由於有些 Javascript 函式不足,也會造成上面同樣的錯誤訊息。
之後試著將 Chrome 更新到最新版,卻又碰到另一個錯誤而無法安裝「安裝失敗,系統不支援您的 windows 版本」,原來Google Chrome 已停止支援 Windows XP 和 Windows Vista,而最後的封印版本為 49.0.2623.112 m。
去下載 Google Chrome v49.0.2623.112 Offline Installer (32-bit) 來進行安裝,之後就一切恢復正常了。
2017年6月1日 星期四
2017年5月26日 星期五
C# WebAPI 與 Angular2 透過 Http.post 傳遞參數做資料新增
之前一篇 提到,透過 http.get 來進行資料的 Query,Query 參數主要是透過網址列來傳遞。
而為了符合 RESTful 架構風格,因此在新增資料時,我們使用的是 http.post
承接上一篇的例子,在這邊我們仍以 ValuesController.cs 作為例子
Step 1. 同樣的步驟,我們在必須先建一個類別來接收 http.post 傳遞過來的參數,這邊我們命名為 MyData
public class MyData
{
public string fab { get; set; }
public string shop { get; set; }
public string date { get; set; }
public string qty { get; set; }
}
Step 2. 將 POST預設的 code 標註起來,因為傳遞的參數不是一的字串(string),而是剛剛建立的 MyData 類別。
Http.post 就是從Post Body 取得參數,前面加的是[FromBody]。function 裡的內容就是透過 SQL 語法去將資料存到資料庫裡。
//// POST api/values
//public void Post([FromBody]string value)
//{
//}
// POST api/values
public void Post([FromBody]MyData value)
{
Console.Write(value);
}
前端 Angular2的部分也很簡單,幾乎只是將原本的 get 改成 post 再多傳遞一個變數"body"
Step 3. 我們在網頁上多加一個按鈕,讓這個按鈕觸發 save()
save(){
let options = new RequestOptions();
let headers = new Headers({ 'Content-Type': 'application/json',
'Accept': 'q=0.8;application/json;q=0.9' });
options.headers = headers;
let body = {
'fab': 'Fab01',
'shop': 'Shop01',
'date': '2017/05/26',
'qty': 100
}
let url = '/api/values/';
this._http.post(url,body, options)
.subscribe(next => console.log('ok'));
}
如此,即完成 Http.post 的實作。
這裡可以透過 Chrome 瀏覽器,打開 F12 編輯視窗,選擇 Network 可以看到傳送出去的http body如下:
Request Payload:
{ "fab": "Fab01", "shop": "Shop01", "date": "2017/05/26", "qty": 100 }
另外也可以 Fiddler 來查看
而為了符合 RESTful 架構風格,因此在新增資料時,我們使用的是 http.post
承接上一篇的例子,在這邊我們仍以 ValuesController.cs 作為例子
Step 1. 同樣的步驟,我們在必須先建一個類別來接收 http.post 傳遞過來的參數,這邊我們命名為 MyData
public class MyData
{
public string fab { get; set; }
public string shop { get; set; }
public string date { get; set; }
public string qty { get; set; }
}
Step 2. 將 POST預設的 code 標註起來,因為傳遞的參數不是一的字串(string),而是剛剛建立的 MyData 類別。
Http.post 就是從Post Body 取得參數,前面加的是[FromBody]。function 裡的內容就是透過 SQL 語法去將資料存到資料庫裡。
//// POST api/values
//public void Post([FromBody]string value)
//{
//}
// POST api/values
public void Post([FromBody]MyData value)
{
Console.Write(value);
}
前端 Angular2的部分也很簡單,幾乎只是將原本的 get 改成 post 再多傳遞一個變數"body"
Step 3. 我們在網頁上多加一個按鈕,讓這個按鈕觸發 save()
save(){
let options = new RequestOptions();
let headers = new Headers({ 'Content-Type': 'application/json',
'Accept': 'q=0.8;application/json;q=0.9' });
options.headers = headers;
let body = {
'fab': 'Fab01',
'shop': 'Shop01',
'date': '2017/05/26',
'qty': 100
}
let url = '/api/values/';
this._http.post(url,body, options)
.subscribe(next => console.log('ok'));
}
如此,即完成 Http.post 的實作。
這裡可以透過 Chrome 瀏覽器,打開 F12 編輯視窗,選擇 Network 可以看到傳送出去的http body如下:
Request Payload:
{ "fab": "Fab01", "shop": "Shop01", "date": "2017/05/26", "qty": 100 }
另外也可以 Fiddler 來查看
2017年4月25日 星期二
建立 C# WebAPI 與 Angular2 做 Http.get 溝通
因為這個部分是小太陽一開始學習 Angular2 首要想完成的地方,中間當然遇到了許多難關,一一的克服後,撰寫這篇文章希望對大家有所幫助!
本範例是前端網頁傳遞多個Query參數,到後端Web API 搜尋資料庫後,將 DataTable 回傳到前端的範例。
Step 1. 建立 C# Web API (vs2012)
1) 新增專案 >> Web >> ASP.NET MVC 4 WEB 應用程式
2) 範本選取 Web API
Web API專案完成建立後,會預設建立一個 ValuesController.cs,我們以此Controller 來進行範例。
Step 2. 因為要傳遞多個參數,所以會用一個類別將參數接起來,所以這邊會建一個 QueryParams 類別,用來接參數。
public class QueryParams
{
public string fab { get; set; }
public string shop { get; set; }
public string date { get; set; } // YYYY/MM/DD - YYYY/MM/DD
}
Step 3. Http.get 是透過 URL 來傳遞參數,所以在接參數的前面加一個 [FromUri],如果是 Http.post 就是從Post Body 取得參數,前面加的是[FromBody]。本範例就不著墨在DBConnector上面了,小太陽用的是 Oracle.ManagedDataAccess。
// GET api/values
//public IEnumerable<string> Get()
//{
// return new string[] { "value1", "value2" };
//}
public DataTable Get([FromUri]QueryParams queryParams)
{
DBConnector db = new DBConnector("MyDB");
string strSQL = @"select '{0}', '{1}', '{2}' from dual";
strSQL = string.Format(strSQL, queryParams.fab
, queryParams.shop
, queryParams.date);
string errorStr = "";
DataTable dt = db.selectSQL(strSQL, out errorStr);
return dt;
}
接下來是前端 Angular2的部分,假設你已經透過這篇建好專案了 ng2 建立新專案
並且解決 Cross Domain問題 解決 ng2 的 Cross Domain 問題
Step 4. 那麼我們開始在 app.component.ts 來呼叫 Http.get 吧
import { Component, OnInit } from '@angular/core';
import {URLSearchParams, Headers, Http, RequestOptions} from '@angular/http';
@Component({
selector: 'app-root',
templateUrl: `
<h1>
<pre>{{data|async|json}}</pre>
</h1>
`,
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
data: any;
constructor(private http: Http){}
ngOnInit(){
let options = new RequestOptions();
let headers = new Headers({ 'Content-Type': 'application/json',
'Accept': 'q=0.8;application/json;q=0.9' });
options.headers = headers;
let params: URLSearchParams = new URLSearchParams();
params.set('fab', 'myFab');
params.set('shop', 'myShop');
params.set('date', '2017/04/24');
options.search = params;
let url = '/api/values/';
this.data = this.http.get(url,options).map(response => response.json());
}
}
如果是使用 Chrome 瀏覽器,打開 F12 編輯視窗,選擇 Network 可以看到傳送出去的網址如下:
這時候在Web API 中設中斷點就可以看到傳進來的參數。
而Angular2 的畫面也會將回傳回來的 DataTable轉為 json放到 data 變數裡,下面是最後網頁呈現的結果:
本範例是前端網頁傳遞多個Query參數,到後端Web API 搜尋資料庫後,將 DataTable 回傳到前端的範例。
Step 1. 建立 C# Web API (vs2012)
1) 新增專案 >> Web >> ASP.NET MVC 4 WEB 應用程式
2) 範本選取 Web API
Web API專案完成建立後,會預設建立一個 ValuesController.cs,我們以此Controller 來進行範例。
Step 2. 因為要傳遞多個參數,所以會用一個類別將參數接起來,所以這邊會建一個 QueryParams 類別,用來接參數。
public class QueryParams
{
public string fab { get; set; }
public string shop { get; set; }
public string date { get; set; } // YYYY/MM/DD - YYYY/MM/DD
}
Step 3. Http.get 是透過 URL 來傳遞參數,所以在接參數的前面加一個 [FromUri],如果是 Http.post 就是從Post Body 取得參數,前面加的是[FromBody]。本範例就不著墨在DBConnector上面了,小太陽用的是 Oracle.ManagedDataAccess。
// GET api/values
//public IEnumerable<string> Get()
//{
// return new string[] { "value1", "value2" };
//}
public DataTable Get([FromUri]QueryParams queryParams)
{
DBConnector db = new DBConnector("MyDB");
string strSQL = @"select '{0}', '{1}', '{2}' from dual";
strSQL = string.Format(strSQL, queryParams.fab
, queryParams.shop
, queryParams.date);
string errorStr = "";
DataTable dt = db.selectSQL(strSQL, out errorStr);
return dt;
}
接下來是前端 Angular2的部分,假設你已經透過這篇建好專案了 ng2 建立新專案
並且解決 Cross Domain問題 解決 ng2 的 Cross Domain 問題
Step 4. 那麼我們開始在 app.component.ts 來呼叫 Http.get 吧
import { Component, OnInit } from '@angular/core';
import {URLSearchParams, Headers, Http, RequestOptions} from '@angular/http';
@Component({
selector: 'app-root',
templateUrl: `
<h1>
<pre>{{data|async|json}}</pre>
</h1>
`,
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
data: any;
constructor(private http: Http){}
ngOnInit(){
let options = new RequestOptions();
let headers = new Headers({ 'Content-Type': 'application/json',
'Accept': 'q=0.8;application/json;q=0.9' });
options.headers = headers;
let params: URLSearchParams = new URLSearchParams();
params.set('fab', 'myFab');
params.set('shop', 'myShop');
params.set('date', '2017/04/24');
options.search = params;
let url = '/api/values/';
this.data = this.http.get(url,options).map(response => response.json());
}
}
如果是使用 Chrome 瀏覽器,打開 F12 編輯視窗,選擇 Network 可以看到傳送出去的網址如下:
Request URL:
http://localhost:4200/api/values/?fab=myFab&shop=myShop&date=2017/04/24
這時候在Web API 中設中斷點就可以看到傳進來的參數。
而Angular2 的畫面也會將回傳回來的 DataTable轉為 json放到 data 變數裡,下面是最後網頁呈現的結果:
[
{
"'MYFAB'": "myFab",
"'MYSHOP'": "myShop",
"'2017/04/24'": "2017/04/24"
}
]
2017年4月17日 星期一
利用 Moment.js 將日期轉換為字串
Step 1. 安裝 moment 套件
npm install moment
Step 2. 在 TypeScript 中 import moment 套件
import * as moment from 'moment';
Step 3. 將日期格做轉為字串語法如下
var mDate = moment();
var today = mDate.format("MM/DD/YYYY"); // 轉為 MM/DD/YYYY 字串格式
var day7 = mDate.add(7,'days').format("MM/DD/YYYY"); // 加7天
2017年4月5日 星期三
解決 ng2 的 Cross Domain 問題
當我們在開發環境使用 Angular2 要去後端 Web API 取資料時,出現以下錯誤
No 'Access-Control-Allow-Origin' header is present on the requested resource.
這是因為後端的 Web API 沒有支援 Cross Origin Resource Sharing (CORS)
這時,我們可以在Client端設定,透過 Proxy 轉發網址
Step 1. 於根目錄(與package.json同層) 建立 proxy.config.json 檔案,內容如下
(其中 KyleAPI 是Web API 的名稱,target 指的是 Visual Studio 執行後產生 IIS Express 的站台IP)
{
"/KyleAPI": {
"target": "http://localhost:47496",
"secure": false
}
}
Step 2. 修改package.json檔案,將npm 指令中的 start 加上proxy-config,並指向proxy.config.json 檔案
"start": "ng serve",
↓↓↓
"start": "ng serve --proxy-config proxy.config.json",
Step 3. 重新啟動 npm start,並在程式中的 url 只要改成下面這段即可
//let url = 'http://localhost:47496/KyleAPI/api/values/';
let url = '/KyleAPI/api/values/';
這時我們的 proxy 設定會自動將 /KyleAPI/api/values/ 網址轉為 http://localhost:47496/KyleAPI/api/values/
當你將開發的 Angular2 與 Web API 部署到 IIS 上之後,請把他們放在一起(詳見這一篇),這時候就不需要這個設定了
No 'Access-Control-Allow-Origin' header is present on the requested resource.
這是因為後端的 Web API 沒有支援 Cross Origin Resource Sharing (CORS)
這時,我們可以在Client端設定,透過 Proxy 轉發網址
Step 1. 於根目錄(與package.json同層) 建立 proxy.config.json 檔案,內容如下
(其中 KyleAPI 是Web API 的名稱,target 指的是 Visual Studio 執行後產生 IIS Express 的站台IP)
{
"/KyleAPI": {
"target": "http://localhost:47496",
"secure": false
}
}
Step 2. 修改package.json檔案,將npm 指令中的 start 加上proxy-config,並指向proxy.config.json 檔案
"start": "ng serve",
↓↓↓
"start": "ng serve --proxy-config proxy.config.json",
Step 3. 重新啟動 npm start,並在程式中的 url 只要改成下面這段即可
//let url = 'http://localhost:47496/KyleAPI/api/values/';
let url = '/KyleAPI/api/values/';
這時我們的 proxy 設定會自動將 /KyleAPI/api/values/ 網址轉為 http://localhost:47496/KyleAPI/api/values/
當你將開發的 Angular2 與 Web API 部署到 IIS 上之後,請把他們放在一起(詳見這一篇),這時候就不需要這個設定了
ng2 檔案資料夾介紹
開發 angular2 必須要有幾個關鍵的資料夾與檔案
a. 資料夾的部分
node_modules
Node.JS 的一些模組
e2e
End-to-end (E2E) Tests 測試用
b. app資料夾裡面
*.spec
Unit Tests 用的檔案
app.module.ts
用來註冊其他的 NgModule 到 root NgModule 裡面
main.ts
用來綁定 platform-browser-dynamic 與 NgModule
c. 檔案部分
package.json
定義有多少 npm 指令可以執行
protractor.config.js
e2e 測試用的config檔
systemjs.config.js
Mapping angular2 載入的模組
a. 資料夾的部分
node_modules
Node.JS 的一些模組
e2e
End-to-end (E2E) Tests 測試用
b. app資料夾裡面
*.spec
Unit Tests 用的檔案
app.module.ts
用來註冊其他的 NgModule 到 root NgModule 裡面
main.ts
用來綁定 platform-browser-dynamic 與 NgModule
c. 檔案部分
package.json
定義有多少 npm 指令可以執行
protractor.config.js
e2e 測試用的config檔
systemjs.config.js
Mapping angular2 載入的模組
2017年4月4日 星期二
ng2 建立新專案
建立 Angular2 專案的步驟,在官網也有介紹。 https://angular.io/docs/ts/latest/cli-quickstart.html
這邊只是單存的紀錄一下自己的學習筆記
Step 1. 必須先安裝 node.js (小太陽裝的是node-v7.3.0-x86.msi 這個版本),安裝完畢即可使用 cmd 操作 npm 指令
查看版本
node -v
npm -v
Setp 2. 設定連外網的 Proxy (如果你的環境需要設定連外網的話)
npm config set proxy=http://192.168.xx.xxx:8080
檢查設定值
npm config list
Step 3. 透過 angular cli 安裝 Angular2 環境
npm install -g angular-cli
Step 4. 安裝完畢後,可以開始操作 ng 指令
查看 help
ng --help
建立一個 demo 專案
ng new 專案名稱
(這個階段要有耐心點,等它跑完,因為小太陽跑到下面這段以為結束了... 強制關閉,結果就是專案Create失敗)
Installing packages for tooling via npm.
(看到下面這段才算建立專案完成)
Project '專案名稱' successfully created.
Step 5. 執行測試
cd 專案名稱
ng serve
開啟網頁輸入 http://127.0.0.1:4200,網頁出現 app works! 表示建立專案成功囉!
這邊只是單存的紀錄一下自己的學習筆記
Step 1. 必須先安裝 node.js (小太陽裝的是node-v7.3.0-x86.msi 這個版本),安裝完畢即可使用 cmd 操作 npm 指令
查看版本
node -v
npm -v
Setp 2. 設定連外網的 Proxy (如果你的環境需要設定連外網的話)
npm config set proxy=http://192.168.xx.xxx:8080
檢查設定值
npm config list
Step 3. 透過 angular cli 安裝 Angular2 環境
npm install -g angular-cli
Step 4. 安裝完畢後,可以開始操作 ng 指令
查看 help
ng --help
建立一個 demo 專案
ng new 專案名稱
(這個階段要有耐心點,等它跑完,因為小太陽跑到下面這段以為結束了... 強制關閉,結果就是專案Create失敗)
Installing packages for tooling via npm.
(看到下面這段才算建立專案完成)
Project '專案名稱' successfully created.
Step 5. 執行測試
cd 專案名稱
ng serve
開啟網頁輸入 http://127.0.0.1:4200,網頁出現 app works! 表示建立專案成功囉!
訂閱:
文章 (Atom)


