iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 30
0
Software Development

三十天利用Angular與.net Core開發實戰一波系列 第 30

Day 30 AngularTri 實作 - 前端頁面 (查詢) & 後記

  • 分享至 

  • xImage
  •  

查詢

最後來實作一個常用功能

透過前端輸入參數給後端API撈資料後回傳頁面

先說說後端的Web API怎麼寫

後端API

  • Models中DataAccess.cs的類別,用來連線MongoDB與增刪修查。
  • 我現在預設條件查詢功能想要達到可選用Id、年、起始月、結束月、縣市別當查詢參數
  • 利用下方網友提供的方法去實作

How do I dynamically apply a conditional operator to a field using the official MongoDB-CSharp-Driver?
C# remove null values from object array
MongoDB C# / .NET Driver 中IMongoQuery的内部实现Query的用法

    public IEnumerable<Triathlon> GetTri(string id, string year, string monthS,string monthE, string place)
  {
    int i = 0;
    var qc = new IMongoQuery[5];
    if (id != "") qc[i++] = Query<Triathlon>.EQ(p => p.Id, new ObjectId(id));
    if (year != "") qc[i++] = Query<Triathlon>.Matches(p => p.year, year);
    var S = Query<Triathlon>.GTE(p => p.month, monthS);
    var E = Query<Triathlon>.LTE(p => p.month, monthE);
    if (monthS != "") qc[i++] =S;
    if (monthE != "") qc[i++] =E;
    if (monthE != ""&& monthE != "") qc[i++] = Query.And(S, E);
    if (place != "") qc[i++] = Query<Triathlon>.Matches(p => p.place, place);
    qc = qc.Where(c => c != null).ToArray();
    if (qc.Length > 0)
       return _db.GetCollection<Triathlon>("Triathlon").Find(Query.And(qc));
    else
      return _db.GetCollection<Triathlon>("Triathlon").FindAll();
 }
  • 一開始init一個IMongoQuery,先預設全部條件都會帶入,所以長度給他5
  • 接下來判斷每個條件是否為空,若不會空就把他加到IMongoQuery
  • 接下來因為加入的條件不一定5個都會加入,所以IMongoQuery中可能會有null
    =>這邊再把null去掉
qc = qc.Where(c => c != null).ToArray();
  • 然後又有可能5個條件都沒有帶,所以沒帶條件參數就預設為搜尋全部

前端

先設定畫面上可以輸入四個參數的物件,年、起始月、結束月、區域,通常也是用input與下拉式選單
這邊起始月跟結束月在原本的collections中沒有這些屬性,
所以我們可以在前端中建一個view model來放置起始月與結束月

VTriathlon.ts
import { Triathlon } from 'src/app/_models/triathlon'; 
export class VTriathlon extends Triathlon { //繼承Triathlon所有屬性
         month_S: string;
         month_E: string;
       }

就可以new一個ngModel來綁定前端輸入值

public queryTridata: VTriathlon = new VTriathlon();
trievent.component.html
<mat-form-field class="standard-width">
    <mat-select placeholder="年" [(ngModel)]="queryTridata.year">
      <mat-option>-</mat-option>
      <mat-option value="2018"> 2018</mat-option>
      <mat-option value="2019"> 2019</mat-option>
      <mat-option value="2020"> 2020</mat-option>
    </mat-select>
  </mat-form-field>
  <mat-form-field class="standard-width">
    <mat-select placeholder="起始月" [(ngModel)]="queryTridata.month_S">
      <mat-option>-</mat-option>
      <mat-option *ngFor="let i of months" [value]="i.CODE">
        {{i.NAME}}
      </mat-option>
    </mat-select>
  </mat-form-field>
  <mat-form-field class="standard-width">
    <mat-select placeholder="結束月" [(ngModel)]="queryTridata.month_E">
      <mat-option>-</mat-option>
      <mat-option *ngFor="let i of months" [value]="i.CODE">
        {{i.NAME}}
      </mat-option>
    </mat-select>
  </mat-form-field>
  <mat-form-field class="standard-width">
    <input matInput placeholder="區域" [(ngModel)]="queryTridata.place">
  </mat-form-field>
  <button mat-fab color="primary" (click)="getTriDataByQuery(queryTridata)">
    <span matTooltip="Search">
      <mat-icon>search</mat-icon>
    </span>
  </button>

連接後API的Function給定型別為VTriathlon的參數
如果輸入參數為有效值即帶上後端API網址,這樣就會去撈資料了

api/Triathlon/GetTriById?year=輸入值&monthS=輸入值&monthE=輸入值&place=輸入值

 public getBackendDataByQuery(parameter: VTriathlon): Observable<Triathlon> {
  const URL = environment.TriBackendAPI + '/Triathlon/GetTriById';
  let myparams = new HttpParams(); //用HttpParams來組參數
  if (this.isValue(parameter.year)) {
    myparams = myparams.set('year', parameter.year);}
  if (this.isValue(parameter.month_S)) {
    myparams = myparams.set('monthS', parameter.month_S);}
  if (this.isValue(parameter.month_E)) {
    myparams = myparams.set('monthE', parameter.month_E);}
  if (this.isValue(parameter.place)) {
    myparams = myparams.set('place', parameter.place);}
  console.log(URL + '?' + myparams);
  return this.http.get<Triathlon>(URL, { params: myparams });//URL與參數帶給後端
}
//判斷輸入值輸入是否為undefined或''
public isValue(item: any) {
  if (item !== undefined && item !== '') {
    return true;
  }
}

串接後端API完成後,在畫面上再設定一個button設定為click後就去後端撈資料
getTriDataByQuery(item: VTriathlon)
最後接回來的資料比照如一開始撈資料的function丟給DataTable去呈現即可

後記

將前面這幾天文章串接在一起,就會完成了一個具有CRUD功能的後台了
這幾篇僅示範了基本的操作邏輯,複雜的商業邏輯再透過前端與後端的搭配,也一定可以完成一個Morden Web

以下為此三十天的程式碼,有興趣的人可以參考,我會繼續維護的

想不到我真的完成了一個自己想用的程式專案,太酷了
很累但也學到很多,真心覺得下去動手做才能獲得你要的

過程就是一切


上一篇
Day 29 AngularTri 實作 - 前端頁面(新增/回前頁 / 新增一筆 / 副檔塞入主檔)
下一篇
Day 0 回歸初衷-鐵人賽結語
系列文
三十天利用Angular與.net Core開發實戰一波32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言