Angular 2 + 折騰記 :(3)初步瞭解服務及使用

CRPER發表於2017-03-23

前言

不探究高深理論,只探究實際使用,有更好的寫法或者經驗請指出;
有些暫時沒涉及到的知識我可能會順著例子解釋;


什麼是服務

簡言之:就是資源獲取,以及通訊邏輯處理的地方;

Angular2的服務引入了依賴注入這個概念。詳情看這個;

【依賴注入:中】
【依賴注入:英】

我看github上有些專案的service寫的很複雜(很重),但是我不大喜歡這樣。
我力求service內少處理複雜邏輯。這可能和每個人的開發理念不一樣。。舉一個例子,看程式碼。

// vehicle-fault.service.ts 


// 服務類必須引入這個
import { Injectable } from '@angular/core';

// 自己封裝的鑑權
import { AuthService } from '../../../services/auth.service';

// 我這裡存放了介面請求地址還有一些公用資訊。nginx做反向代理所以不走baseurl
import { environment } from '../../../../environments/environment';

// 不可忘記括號,任何裝飾器都一樣,防止莫名的錯誤
@Injectable()
export class VehicleFaultService {

  // DI(依賴注入)  
  // 常規的寫法 this.authHttp = new AuthService();
  // 這個寫法也是可以的,官方不推薦,說不好維護(當專案大起來的時候)
  constructor(private authHttp: AuthService) { }

  // 獲取故障提示列表
  VehicleFaultList(data) {
    return this.authHttp.post(environment.baseUrl + 'VehicleFault/VehicleFaultList', data);
  }

  // 獲取單個車輛的故障列表
  SingleVehicleFaultList(data) {
    return this.authHttp.post(environment.baseUrl + 'VehicleFault/SingleVehicleFaultList', data);
  }

  // 根據車輛ID獲取單車資訊
  VehicleDetail(data) {
    return this.authHttp.post(environment.baseUrl + 'Vehicle/VehicleDetail', data);
  }

  // 清除故障碼
  ClearFault(data) {
    return this.authHttp.post(environment.baseUrl + 'VehicleFault/ClearFault', data);
  }

  // 這裡的每個介面返回一個可觀察的訂閱物件
}複製程式碼

那麼我們應該如何讓服務可以正常使用呢?

大致有那麼兩種;

  • 模組內注入,整個模組內的components皆可以使用
    import { NgModule } from '@angular/core';  -- 內建

    // 除了根模組用BrowserModule,其他一些模組需要用到一些內建指令(*ngIf,*ngFor這些的)必須引入這個 -- 內建
    import { CommonModule } from '@angular/common'; 

    // 路由模組 -- 內建
    import { RouterModule } from '@angular/router';

    // 表單模組,及響應式表單模組 -- 內建
    import { FormsModule, ReactiveFormsModule } from '@angular/forms';
    import { VehicleFaultRoutes } from './vehicle-fault.routes';

    // service 
    import { VehicleFaultService } from './vehicle-fault.service';

    // component
    import { VehicleFaultComponent } from './vehicle-fault.component';
    import { ListComponent } from './list/list.component';
    import { DetailComponent } from './detail/detail.component';
    import { CleanComponent } from './clean/clean.component';

    // public module
    import { MitPipeModule } from '../../../widgets/mit-pipe/mit-pipe.module';
    import { MitDataTableModule } from '../../../widgets/mit-data-table/mit-data-table.module';
    import { MitAlertModule } from '../../../widgets/mit-alert/mit-alert.module';
    import { MitLoadingModule } from '../../../widgets/mit-loading/mit-loading.module';
    import { DepartmentSelectModule } from './../../../share/department-select/department-select.module';
    const mitModule = [
      MitPipeModule,
      MitDataTableModule,
      MitAlertModule,
      MitLoadingModule,
      DepartmentSelectModule
    ];

    @NgModule({
      imports: [ // 引入相關的模組
        ...mitModule,
        FormsModule,
        RouterModule,
        CommonModule,
        VehicleFaultRoutes
      ],
      declarations: [VehicleFaultComponent, ListComponent, DetailComponent, CleanComponent], // 宣告元件
      providers: [VehicleFaultService] // 服務注入
      // providers : [{provide:vfualt, useClass:VehicleFaultService}] // 這是一種別名的寫法
    })
    export class VehicleFaultModule { }複製程式碼
// 引入一些生命週期的控制,元件值傳遞響應介面等
import { Component, OnInit, AfterContentInit, OnChanges, SimpleChanges, OnDestroy } from '@angular/core';

// 引入路由模組
import { Router, ActivatedRoute } from '@angular/router';

// 基類
import { MitDataTableBase } from '../../../../widgets/mit-data-table/mit-data-table-base';

// 服務
import { VehicleFaultService } from '../vehicle-fault.service';
import { EventsService } from '../../../../services/events-service.service';

// 動畫
import { fadeIn } from '../../../../animation/fadeIn';

@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.scss'],
  animations: [fadeIn]
})
export class ListComponent extends MitDataTableBase implements OnInit, OnDestroy {
  private getRenderList: any;
  private currentItem: any;

  private showAlert = false;
  constructor(
    private vehicleFaultService: VehicleFaultService, 
    private eventsService: EventsService, 
    private router: Router, 
    private activatedRoute: ActivatedRoute
  ) {
    super(router, activatedRoute);
  }
  ngOnInit() {
  }
}


// 若是要使用別名注入,還需要引入Inject,從core裡面 -- 在components
// 然後放在construcor裡面,寫法如下
// constructor(@Inject('vfault') private vehicleFaultService: any)
// 這樣就可以使用了,且在components內不需要引入對應的服務!!!!複製程式碼
  • 單一components內注入,自己使用

元件內用providers引入

// 服務
import { vehicleFaultService } from '../vehicle-fault.service';
import { EventsService } from '../../../../services/events-service.service';

// 動畫
import { fadeIn } from '../../../../animation/fadeIn';

@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.scss'],
  animations: [fadeIn],
  providers: [vehicleFaultService, EventsService]
})複製程式碼

總結

  1. 服務若是結合@Inpu(),@Output()..感覺不需要ngrx這種狀態管理
  2. 服務可以貫穿全域性(全域性注入),事件廣播這些都可以實現
  3. 服務不應該太重(比如處理一些複雜的邏輯),一個服務內部應該清晰,簡潔。。

最最重要的。。還是多查閱官方的API,然後動手實踐,才能讓你上手快起來。。。

相關文章