服务 angular 与自定义 class?

Service angular vs custom class?

我想知道创建服务的方法。

我从服务器 RegistryItem[] 获取数据为 JSON。

选择哪种方式来创建处理每个 RegistryItem 的服务或创建包含 delete()edit() 等所有逻辑的 class RegistryItem?

class RegistryService {
   edit(registry);
   delete();
   drawRegister();
}

class RegistryItem {
    edit();
    delete();
    drawRegister();

    // Other logic for drawing registry
}

换句话说,我应该将响应项包装成逻辑 class 还是更好地将逻辑移至特定服务?

最佳实践要求您将模型和业务逻辑分开。你的模型(类型或接口)应该只执行数据没有任何行为,你让可注入services 操纵你的模型:

export interface RegistryItem {
 id: number;
 // other related properties
}

并且您的服务应包含与操纵您的 RegistryItem 相关的逻辑:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class RegistryItemService {
// your backend base api url
baseUrl = 'http://localhost:3000/api';
getAll() : Observable<RegistryItem[]> {
   return this.http.get<RegistryItem[]>(this.baseUrl+ '/registry-items')
}
update(item: RegistryItem) : Observable<RegistryItem> {...}
create(item: RegistryItem) : Observable<any> {...}
delete(id: number) : Observable<any> {...}
drawRegister() {...};
}

此服务可以稍后注入并在您的组件中使用,如下所示

注册表-item.component.ts

@Component({
  selector: 'app-registry-item',
  templateUrl: './registry-item.component.html',
})
export class RegistryItemComponent {
  registryItems: RegistryItem[] = [];
  constructor(private service: RegistryItemService ) { 
    this.service.getAll().subscribe(res=>  {
            this.registryItems = res;
           },
         err=> console.error(err)
      );
  }

}

注册表-item.component.html

<div>
  <h1>Registry items<h1/>
   <!-- 
     show your data in a list or table or whatever you like
    -->
   <ul>
    <li *ngFor="let i of registryItems"> 
      <span>{{i.id}} </span>
      <!-- show other info
       <span>{{i.name}} </span> -->
    </li>
   </ul>
</div>

我会选择单例服务。 因此,无论您将其注入到应用程序的哪个位置,您始终共享同一个服务实例(没有理由创建该服务的多个实例)。 我们可以通过在可注入装饰器的“root”或“plaform”中提供它来实现这一点(参见下面的示例):

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Employee } from '../shared/employee';
import { Observable, throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})

export class RestApiService {
  
  // Define API
  apiURL = 'http://localhost:3000';

  constructor(private http: HttpClient) { }

  /*========================================
    CRUD Methods for consuming RESTful API
  =========================================*/

  // Http Options
  httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/json'
    })
  }  

  // HttpClient API get() method => Fetch employees list
  getEmployees(): Observable<Employee> {
    return this.http.get<Employee>(this.apiURL + '/employees')
    .pipe(
      retry(1),
      catchError(this.handleError)
    )
  }

  // HttpClient API get() method => Fetch employee
  getEmployee(id): Observable<Employee> {
    return this.http.get<Employee>(this.apiURL + '/employees/' + id)
    .pipe(
      retry(1),
      catchError(this.handleError)
    )
  }  

  // HttpClient API post() method => Create employee
  createEmployee(employee): Observable<Employee> {
    return this.http.post<Employee>(this.apiURL + '/employees', JSON.stringify(employee), this.httpOptions)
    .pipe(
      retry(1),
      catchError(this.handleError)
    )
  }  

  // HttpClient API put() method => Update employee
  updateEmployee(id, employee): Observable<Employee> {
    return this.http.put<Employee>(this.apiURL + '/employees/' + id, JSON.stringify(employee), this.httpOptions)
    .pipe(
      retry(1),
      catchError(this.handleError)
    )
  }

  // HttpClient API delete() method => Delete employee
  deleteEmployee(id){
    return this.http.delete<Employee>(this.apiURL + '/employees/' + id, this.httpOptions)
    .pipe(
      retry(1),
      catchError(this.handleError)
    )
  }

  // Error handling 
  handleError(error) {
     let errorMessage = '';
     if(error.error instanceof ErrorEvent) {
       // Get client-side error
       errorMessage = error.error.message;
     } else {
       // Get server-side error
       errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
     }
     return throwError(errorMessage);
  }

}

这个例子不是我出的,我是从这个guide拿来的。 但我很确定我会实现或多或少完全相同的代码,所以只是复制它。

只是对代码的一些评论:

我不会在服务中定义 API URL 端点,您可能需要从不同的环境(例如 local/QA/prod)访问不同的 API,所以我会将端点作为字符串存储在由 Angular CLI 自动创建的环境文件(例如 environment.[targetENV].ts)中。当然,如果您计划从每个 ENV 访问始终相同的 API,您可以完全按照示例中的方式进行。否则,您可以为您拥有的每个环境文件分配一个不同的 API 端点,然后将其导入您的服务以使用它。 ENV文件截图:

这是您可能希望如何构建 env 文件的示例。

export const environment = {
production: false,
API_URL: 'http:/blabla.com/blabla/api',
API_EMPLOYEE: 'http://test.api.com/test-api/api',

};

如果您的代码可能用在运行多个 Angular 应用程序的一个网页上,您可能希望在“平台”而不是“根目录”中提供它。 100%只使用一个服务实例。

要实现这一点,只需更改可注入装饰器:

@Injectable({
  providedIn: 'root'
})

至:

@Injectable({
  providedIn: 'platform'
})