首页 文章

使用Angular 4注入接口

提问于
浏览
1

我正在尝试创建一个通用的 DeleteableConfirmationComponent ,这将允许我显示一个确认对话框,并从实现 Deleteable infterface的任何注入服务中调用 delete 方法 .

为此,我创建了这个接口:

export interface Deleteable {
  delete(object);
}

我有一个实现它的服务:

@Injectable()
export class LocalityService implements Deleteable {
  delete(locality): Observable<Locality> {
    // Delete logic.
  }
}

对于 DeleteableConfirmationComponent ,我试图使用构造函数注入服务:

export class DeleteableConfirmationComponent {
  constructor(
    public dialog: MdDialogRef<DeleteableConfirmationComponent>,
    @Inject(MD_DIALOG_DATA) public data: any,
    private service: Deleteable
  ) {}

  delete() {
    this.service.delete(this.object)
                .subscribe(() => {
                  this.dialog.close();
                });
  }
}

但不幸的是,我有一个错误说 it can't resolve all parameters for DeleteableConfirmationComponent .

现在,我正在使用对话框数据选项,以便传递我的服务:

confirmDelete(locality) {
  this.dialog.open(DeleteableConfirmationComponent, {
    data: {
      service: this.localityService
    }
  });
}

但它感觉很脏,并允许注入任何类型的服务,而我想强制实现 Deleteable 接口的服务 .

我以为我可能会更好地使用 abstract class ,但我更喜欢继承的构图 .

任何想法或最佳实践建议?

2 回答

  • 0

    InjectionToken 可以替换已弃用的 OpaqueToken

    export const AuthenticationProvider = new InjectionToken(
      "AuthenticationProvider",
      { providedIn: "root", factory: () => new CognitoAuthenticationProvider() }
    );
    
    ...
    
    @Injectable()
    export class CognitoAuthenticationProvider implements IAuthenticationProvider {
    
    ...
    
    @Injectable({
      providedIn: "root"
    })
    export class AuthenticationService {
      constructor(
        @Inject(AuthenticationProvider)
        private authenticationProvider: IAuthenticationProvider,
        private http: HttpClient
      ) {}
    
  • 2

    如评论中所述,您可以将接口转换为抽象类:

    export abstract class Deleteable {
      abstract delete(object);
    }
    

    然后在您的提供商中,您可以将其映射到真实的类:

    providers: [{ provide: Deleteable, useValue: new LocalityService() }]
    

    你可能不喜欢这种方法,因为现在似乎 LocalityService 必须扩展 Deleteable . 但是如果 LocalityService 需要扩展其他类呢?不允许多重继承:

    // Error: Classes can only extend a single class
    export class LocalityService extends OtherClass, Deleteable { }
    

    或者您可能根本不喜欢 Deleteable 现在将出现在 LocalityService 原型链中的事实:

    export class LocalityService extends Deleteable {
      delete(locality): void {
        // Returns true
        alert(this instanceof Deleteable);
      }
    }
    

    但是,如this answer所示,TypeScript允许您将类视为接口 . 因此,您可以将 implements 与抽象类一起使用 .

    export class LocalityService extends OtherClass implements Deleteable {
      delete(locality): void {
        // Returns false
        alert(this instanceof Deleteable);
      }
    }
    

    因此,对于所有意图和目的,您的抽象类现在表现得像一个接口 . 它甚至不会出现在原型链中 .

相关问题