【问题标题】:Angular: How to send a string to an injection service?Angular:如何将字符串发送到注入服务?
【发布时间】:2018-01-04 01:18:28
【问题描述】:

我为crud任务创建了通用服务,该服务通过DI(依赖注入)使用HttpClient,但我需要在服务的构造函数中通知另一个值,如何做到这一点?

因为当我在我的类的构造函数中定义将使用 DI 使用 CRUD 服务时,无法将参数传递给构造函数

下面是服务

import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { CrudInterface } from "@app/core/crud.interface";
import { environment } from "@env/environment";
import { Observable } from "rxjs/Observable";

@Injectable()
export class CRUD<T> implements CrudInterface<T>{
    
    endpoint: string;

    constructor(private http: HttpClient, routeDir: string){
        this.endpoint = `${environment.endpoint}/${routeDir}`;
    }
    
    getAll(): Observable<T[]> {
        return this.http.get<T[]>(`${this.endpoint}`);
    }

    get(id: number): Observable<T> {
        return this.http.get<T>(`${this.endpoint}/${id}`);
    }

    create(object: T): Observable<T> {
        return this.http.post<T>(`${this.endpoint}`, object);
    }

    update(object: T): Observable<T> {
        return this.http.put<T>(`${this.endpoint}`, object);
    }

    delete(id: number): Observable<any> {
        return this.http.delete<T>(`${this.endpoint}/${id}`);
    }

}

import { Usuario } from "@app/usuarios/model/usuario";
import { CRUD } from "@app/core/crud.service";

class TestCrudServide {

    constructor(
        /**
         * How to inform the parameter here?
         * in this case the endpoint (2nd parameter of the CRUD service)
         */
        private crudService: CRUD<Usuario>
    ){ }

    getAll(){
        this.crudService.getAll();
    }
}

更新

利用 Sannon Aragão(感谢)提出的工厂概念解决方案,我创建了用于动态创建实例的服务提供者

https://angular.io/guide/dependency-injection#factory-providers

export class crudServiceProvider {

    static getProvider(routeDir: string) {
        return {
            provide: CRUD,
            deps: [HttpClient],
            useFactory: (dep) => {
                return new CRUD(dep, routeDir);
            }
        }
    }
}

在我的组件中

@Component({
  selector: 'app-revenda',
  templateUrl: './revenda.component.html',
  styleUrls: ['./revenda.component.css'],
  providers:[ crudServiceProvider.getProvider('/api/revenda') ]
})
export class RevendaComponent implements OnInit {

  constructor(
      private crudService: CRUD<Revenda>
    ) { }
    
    ngOnInit() {
      // now it's work with the correct path and type!
      this.crudService.get(1).subscribe(item => console.log(item));
    }
}

【问题讨论】:

    标签: angular dependency-injection dependencies code-injection


    【解决方案1】:

    Filipe,来自你想为你提供服务的模块:

    {
    provide: 'userService1',
    deps: [ HttpClient ],
    useFactory: (dep1 ) => {
        return new UserService( dep1, 'test');
      }
    }
    

    在您将使用服务的组件中:

    constructor( @Inject('userService1') private userService: UserService ) { }
    

    在 CRUD API 中,您将参数作为字符串获取:

    constructor( private http: HttpClient, private s: string) {
      console.log(s); // will print 'test'
    }
    

    【讨论】:

      【解决方案2】:

      我不相信你可以通过依赖注入的工作方式做到这一点。你可以做的是创建一个基本的 CRUD 类

      export class CRUD<T> implements CrudInterface<T>{
      
          endpoint: string;
      
          constructor(private http: HttpClient, routeDir: string){
              this.endpoint = `${environment.endpoint}/${routeDir}`;
          }
      
          getAll(): Observable<T[]> {
              return this.http.get<T[]>(`${this.endpoint}`);
          }
      
          get(id: number): Observable<T> {
              return this.http.get<T>(`${this.endpoint}/${id}`);
          }
      
          create(object: T): Observable<T> {
              return this.http.post<T>(`${this.endpoint}`, object);
          }
      
          update(object: T): Observable<T> {
              return this.http.put<T>(`${this.endpoint}`, object);
          }
      
          delete(id: number): Observable<any> {
              return this.http.delete<T>(`${this.endpoint}/${id}`);
          }
      
      }
      

      然后创建一个扩展 CRUD 类的 Injectable 服务

      @Injectable()
      export class UserService extends CRUD<Usario> {
          constructor(http: HttpClient){
              super(http, 'users');
          }
      }
      

      UserService 是您在 AppModule 中提供并注入到您的组件中的类。你可以看到 super 被用来传入routeDir 参数。这是一个 stack blitz 演示这个。

      【讨论】:

      • 我明白了,所以我的意图是行不通的......我想创建一个通用服务,因为不必创建其他服务来实现基本的 crud 服务,从而避免创建几个具有相同功能的文件,但感谢您的解决方案,我会使用它
      • @FilipeMansano 我想说拥有这些“中间层”类很好。假设可以做类似constructor(private crudService('user'): CRUD&lt;Usario&gt;){} 的事情。如果要将它添加到多个组件,每个组件都必须指定传入的字符串。使用中间层类,您只需导入和注入。
      【解决方案3】:

      你不能在构造函数中实现任何东西。您必须注入 httpservice 对象(crudservice),并且必须将参数传递给函数。

      要实现第二个,你必须做这样的事情

      this.crudService.get(10);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-04-19
        • 1970-01-01
        • 1970-01-01
        • 2014-07-19
        • 2015-10-20
        • 1970-01-01
        • 2021-11-20
        相关资源
        最近更新 更多