ASP.NET CoreとAngularでWebページを開発
Visual Studioを使用したASP.NET Core開発でAngularのページを作成する。サーバからデータを受信したり、ページに入力した値をPostする方法について記載する。
環境
Windows 10 ver 10.0.17134
Visual Studio Community 2017 ver 15.7.1
.NET Framework ver 4.7.03056
.NET Core Framework ver 2.0.7
Angular ver 4.2.5
Getする
component.ts側は、http.getでASP側のコントローラ(クラス名+メソッド名)に対応したURLを指定する。データはthis.productsに格納される。
http.get(this.baseUrl + 'api/OrderData/Stocks').subscribe(result => {
this.products= result.json() as Product[];
ASPのコントローラは、ルーティング属性がHttpGetで、クラス名+メソッド名が一致するメソッドにマッピングされる。
[Route("api/[controller]")]
public class OrderDataController : Controller
{
[HttpGet("[action]")]
public IEnumerable<Product> Stocks()
{
return new ProductDao().GetStocks();
}
受け渡しするデータ(ここでは『 Product[] 』)は、ASP側とts側に同じものを入れる型を用意する。ASP側はgetter等を実装する予定のためクラスを作成する。ts側はJSONを受け取るときの型定義に使うだけなので、同名で内容は空のインタフェースを作成する。ts側の型でメソッドを実装したければクラスでも構わないし、Stock等の別名にしてもよい。
public class Product
{
public int Id { get; set; }
public string ProductName { get; set; }
public bool WithReport { get; set; }
public string TicketNo { get; set; }
}
interface Product{
}
データをtsとhtmlとの間で受け渡す
htmlではNgForOfディレクティブでデータの件数分ループし、テーブル行を作成する。インデックス(『i』)が振られるので、エレメントに『i』を含めたidを割り当てる。
<p *ngIf="!products"><em>Loading...</em></p>
<table *ngIf="products">
<thead>
<tr>
<th>品名</th>
<th>レポート有り</th>
<th>伝票No.</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let product of products; index as i">
<td><input type="text" id="product_name-{{ i }}" value="{{ product.productName }}" (blur)="GetStockInfo()" /></td>
<td><input type="checkbox" id="with_report-{{ i }}" checked="{{ product.reportChecked }}" /></td>
<td>{{ product.ticketNo }}</td>
</tr>
</tbody>
</table>
ts側からは、行インデックスを含めたidによって、getElementById()メソッドで値が取得できる。
this.updateList= new Array();
for (var i = 0; i < this.rowCount; i++) {
var item = new Product();
item.withReport = (<HTMLInputElement>document.getElementById("with_report-" + i.toString())).checked;
item.productName = (<HTMLInputElement>document.getElementById("product_name-" + i.toString())).value;
updateList.push(item);
}
Postの場合
データ更新処理等でtsからPostするときは、パラメタを持って、http.postをする。Getと同じくASP側のコントローラに対応したURLを指定する。
public updateList: Array<Product> | undefined;
this.http.post(this.baseUrl + 'api/UpdateData/Stocks', updateList).subscribe(result => {
ASPのコントローラは、ルーティング属性がHttpPostのメソッドにマッピングされる。PostによってリクエストBodyに格納されているデータは[FromBody]属性を付けることにより、受け取りが可能となる。
[HttpPost("[action]")]
public void Stocks([FromBody] List<Product> updateList)
{
new ProductsDao().InsertProduct(new ConvertProducts(updateList));
}
表示、非表示を切り替える
NgIfディレクティブで切り替える。値はboolean型ならtrueのとき表示する。配列型ならnullでないとき表示する。
<div *ngIf="showBlock"></div>
<p *ngIf="!products"></p>
public products: Product[] | undefined;
public showBlock: boolean = true;
boolean型なら反転させるだけで切替できる。
this.showBlock= !this.showBlock;
ボタンに割り当てるならこんな感じ。
<input type="submit" value="表示切替" (click) ="showBlock= !showBlock" />
URLパラメタを受け渡す
URLパラメタを付けて遷移するにはrouter.navigateを使う。
public router: Router | undefined;
var param = "data";
this.router.navigate(['proposal'], { queryParams: { id: param} });
受け取る側のtsは、コンストラクタでwindow.location.hrefを参照する。
var url = window.location.href;
下記のエラーが出る場合がある。
ReferenceError: window is not defined
以下のようにプラットフォームを調べてから実行すれば、エラーは出なくなる。
public isBrowser: boolean;
constructor(http: Http, @Inject('BASE_URL') baseUrl: string) {
this.isBrowser = isPlatformBrowser(PLATFORM_ID);
if (this.isBrowser) {
var url = window.location.href;