【问题标题】:How to create a generic service in Aurelia Typescript如何在 Aurelia Typescript 中创建通用服务
【发布时间】:2018-01-03 10:54:16
【问题描述】:

我目前使用 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
}

【问题讨论】:

  • 正确的答案是使用装饰器。您仍然需要为每种类型创建一个类,但您可以使用装饰器添加所需的功能。话虽这么说,创建装饰器可能有点混乱,所以我不会提供答案,除非你想让我展示如何去做,因为它有点涉及,但一旦创建就很容易使用..大部分。
  • 请告诉我怎么做。这可能是我一直在寻找的答案。请指教

标签: javascript typescript dependency-injection aurelia


【解决方案1】:

这是一个使用泛型和打字稿的基本示例。接口应与 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();
    }
}

【讨论】:

  • 我明白了。所以你让消费者通过urlapi。
  • 是的,如果适合您,这是一种简单的方法。另一个想法可能是使用继承(添加到上面的示例中)
  • 您认为可以使用继承添加示例使用者吗?
【解决方案2】:

您是否已经查看过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 中并使用泛型)。

【讨论】:

  • 谢谢。会检查这个
猜你喜欢
  • 2017-04-29
  • 1970-01-01
  • 1970-01-01
  • 2020-04-15
  • 2016-04-13
  • 2015-01-02
  • 1970-01-01
  • 2016-12-25
  • 1970-01-01
相关资源
最近更新 更多