如何在 Aurelia Typescript 中创建通用服务

How to create a generic service in Aurelia Typescript

我目前使用 Aurelia 作为我的前端框架和 Typescript。我有 5 个具有基本 crud 功能的实体。如何创建通用服务,以免创建 5 个具有相同功能的文件?这是我到目前为止所拥有的。如果我可以将它转换为通用类型并仅传递 api url,那就太好了。谢谢

import { HttpClient, json } from "aurelia-fetch-client";
import { inject } from "aurelia-framework";

@inject(HttpClient)
export class WheelTypeService {
    public wheelTypes: WheelType[];
    private http: HttpClient;

    constructor(http: HttpClient) {
        http.configure(config => config.useStandardConfiguration());
        this.http = http;
    }

    getAll() {
        var promise = new Promise((resolve, reject) => {
            if (!this.wheelTypes) {
                this.http.fetch('/api/WheelTypes')
                    .then(result => result.json() as Promise<WheelType[]>)
                    .then(data => {
                        this.wheelTypes= data;
                        resolve(this.wheelTypes);
                    })
                    .catch(err => reject(err));
            } else resolve(this.wheelTypes);
        });

        return promise;
    }
 // omitted some of the crud functionalities
}

您是否已经看过 https://github.com/SpoonX/aurelia-orm?我想,这就是您要找的:

您的 WheelType 可能会变成这样:

@resource('/api/WheelTypes') // important point
export class WheelType {
  ...
}

在你的视图模型中你会做:

@inject(EntityManager)
export class WheelTypeVM {
    constructor(entityManager) {
      this.repository = entityManager.getRepository('user');
    }

    // your CRUD comes here, e.g.
    getAll() {
      return this.repository.find()
        .then(data => {
           this.wheelTypes = data;
        });
    }
}

这只是一小段摘录,还有一些其他的事情要做(插件配置)。但是,您将为每个实体保存服务(或者您甚至可以将代码包装在 VM 中并使用泛型)。

这是一个使用泛型和打字稿的基本示例。接口应与 api 返回的 json 的结构相匹配。希望这对您有所帮助...

import { autoinject } from "aurelia-framework";
import { HttpClient } from "aurelia-http-client";

export interface IReturnType1 {
    id: number;
    name: string;
}

export interface IReturnType2 {
    id: number;
    height: string;
    weight: string;
}

@autoinject
export class GenericService {
    constructor(private http: HttpClient) { }

    getOne<T>(url: string): Promise<T> {
        return this.http
            .get(url)
            .then(response => response.content);
    }

    getAll<T>(url: string): Promise<T[]> {
        return this.http
            .get(url)
            .then(response => response.content);
    }
}

@autoinject
export class ConsumerExample {
    constructor(private svc: GenericService) { }

    async getAllReturnType1(){
        const result = await this.svc.getAll<IReturnType1>("url/for/request/1");
    }

    async getOneReturnType2(){
        const result = await this.svc.getOne<IReturnType2>("url/for/request/2");
    }
}

继承示例...

import { autoinject } from "aurelia-framework";
import { HttpClient } from "aurelia-http-client";

export interface IReturnType1 {
    id: number;
    name: string;
}

export interface IReturnType2 {
    id: number;
    height: string;
    weight: string;
}

export interface IRequestUrls {
    getOne: string;
    getAll: string;
}

@autoinject
export abstract class GenericService<T> {
    constructor(private http: HttpClient) { }

    abstract urls: IRequestUrls;

    getOne(): Promise<T> {
        return this.http
            .get(this.urls.getOne)
            .then(response => response.content);
    }

    getAll(): Promise<T[]> {
        return this.http
            .get(this.urls.getAll)
            .then(response => response.content);
    }
}

export class Request1 extends GenericService<IReturnType1> {
    urls: {
        getOne: "/url/for/request/1";
        getAll: "/url/for/request/1/all";
    };
}

export class Request2 extends GenericService<IReturnType2> {
    urls: {
        getOne: "/url/for/request/2";
        getAll: "/url/for/request/2/all";
    };
}

@autoinject
export class ConsumerExample {
    constructor(
        private r1: Request1,
        private r2: Request2
    ) { }

    async getAllReturnType1() {
        const result = await this.r1.getAll();
    }

    async getOneReturnType2() {
        const result = await this.r2.getOne();
    }
}