如何在Typescript中动态设置类的函数?

时间:2018-10-08 17:31:30

标签: angular typescript

我有一个带有a和b函数的基类。

我想扩展(或创建可能具有功能a或b(或两者都有)的此类的实例,这样,如果我创建BaseClassWithA并尝试调用instance.b(),我将得到编译错误。

具体来说,这是针对基本CRUD Api的,我将在其中使用各种特定的API实例(例如“ UsersAPI”)对其进行扩展。假设Users API可能只有“ GET”作为允许的方法。因此,如果我/另一个开发人员去调用UsersAPI.delete,他们将收到编译错误。

以下是基本API类的示例:

export class CRUDBaseAPI<T extends ApiBaseType> {

    constructor(
        protected apiConfig: ApiConfig,
        protected http: HttpClient,
        protected errorService: ErrorService,
        protected allowedMethods: Method[] = ['get', 'update','delete'],
        protected httpConfig?: HttpConfiguration,
    ) {
    }

    public get(entity: T, httpConfig?: HttpConfiguration): Promise<T> {
        return this.http.get<T>(`${this.apiConfig.url}/${entity.id}`, this.getFullHttpConfiguration(httpConfig)).toPromise()
            .then(returnData)
            .catch(this.handleError(`Unable to retrieve ${this.apiConfig.entityName} record.`));
    }


    public update(entity: T, httpConfig?: HttpConfiguration): Promise<T> {
        return this.http.post(`${this.apiConfig.url}/${entity.id}`, entity, this.getFullHttpConfiguration(httpConfig)).toPromise()
            .then(returnData)
            .catch(this.handleError(`Unable to update ${this.apiConfig.entityName} record.`));
    }

    public delete(entity: T, httpConfig?: HttpConfiguration): Promise<T> {
        // TODO open confirm modal here and delete only if user confirms
        return this.http.delete(`${this.apiConfig.url}/${entity.id}`, this.getFullHttpConfiguration(httpConfig)).toPromise()
            .then(returnData)
            .catch(this.handleError(`Unable to delete ${this.apiConfig.entityName} record.`));
    }
}

function returnData(httpResponse: any) {
    return httpResponse;
}

2 个答案:

答案 0 :(得分:0)

我认为您正在寻找其他东西。您可以实现某种中间件。例如:

public delete(entity: T, httpConfig?: HttpConfiguration): Promise<T> {
    // the userService can hold the logged user that has a permissions array from database of whatever storage service you are using
    let canAccess = this.authService.loggedUser.permissions.includes('user.delete');
    if(!canAccess){
        // show a toaster or an 'access denied' error.
    }
}

是的,您必须在每种方法中编写这些行。但是您可以像这样在服务中提取它:

class AuthService{
    authorize(permission){
       let canAccess = this.loggedUser.permissions.includes(permission);
        if(!canAccess){
            throw new Error('Access denied!'); // you can intercept this Error and display it to the user
        }
    }
}

export class UserAPI<T extends ApiBaseType> {

    public delete(entity: T, httpConfig?: HttpConfiguration): Promise<T> {
        this.authService.authorize('user.delete')
        // your processing
    }
}

答案 1 :(得分:0)

您可以使get中的updatedeleteCRUDBaseAPI方法受到保护,然后在每个子类中,用琐碎的包装器覆盖要公开的方法只是调用超级方法。