打字稿:注入通用&安培;获得ES6模块名称 [英] Typescript: Inject generic & get ES6 module name

查看:198
本文介绍了打字稿:注入通用&安培;获得ES6模块名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想建立一个使用通用存储库:


  • 打字稿

  • ES6

  • 角的1.x

但我想不出我应该怎么注入实体,然后获取其模块名称。

为什么我想要得到的名称的原因:
是因为我遵循命名约定,其中一个名为订单count.ts应该呈现的URL'/顺序/计数

这是可以解决的与打字稿/ JavaScript的?

这里是我有:

订单module.ts

 进口{}应用程序从../../App';
进口{} OrderService从'./order-service';常量模块:ng.IModule = App.module('app.order',[]);module.service('orderService',OrderService);

订单service.ts

 进口{} CrudService从'../../shared/services/crud-service
进口{}定单计数从'../order/entities/order-count';出口类OrderService {
    // @ngInject
    构造函数(私人crudService:CrudService<&定单计数GT;){
        this.crudService = crudService;
    }    getOrders(){
        VAR承诺= this.crudService.getAll();        promise.then(响应=> {
            的console.log(回应,成功);
        }错误=> {
            的console.log(错误,'失败');
        });
    }
}

订单count.ts

 从../../../shared/models/entity进口{}实体;出口类定单计数扩展实体{
    STOREID:字符串;
    STORENAME:字符串;
}

entity.ts

 导出接口IEntity {
    身份证号;
}

entity.ts

 进口{} IEntity从'../../module/contracts/entities/entity';出口类实体实现IEntity {
    新(){}
    身份证号;
}

CRUD-service.ts

 使用严格的;
进口{}的实体从'../models/entity';
进口{} EndpointService从'./endpointService';出口类CrudService< TEntity扩展实体GT; {
    私人baseCallPath:字符串;
    私有实体:{新的():实体};    // @ngInject
    构造函数(私人endpointService:EndpointService,私人$ HTTP:ng.IHttpService){
        。this.baseCallPath =新this.entity()constructor.name.replace(' - ','/');
    }    GETALL():ng.IHttpPromise<&任何GT; {
        返回this.handleResponse(
            这一点。$ http.get(this.endpointService.getUrl(this.baseCallPath))
            '得到所有'
        );
    }    用handleResponse(承诺:ng.IHttpPromise<任何>中callerMethodName:字符串):ng.IHttpPromise<&任何GT; {
        返回promise.success((数据:任何)=> {
            Array.prototype.push.apply(this.baseCallPath,数据);
        })错误((原因:任意)=> {
            的console.log(this.baseCallPath + callerMethodName,错误,原因);
        });
    }
}

端点service.ts

 出口类EndpointService {
    私人基本URI:字符串=的http://本地主机:3000 / API /';    的getURL(MODULENAME:字符串):字符串{
        返回this.baseUri + MODULENAME;
    }
}


解决方案

对于类名称的使用作为一种价值则可能检查的此相关的问题

可以检索和使用为 Foo.name好事 this.constructor.name 。坏的是,它是不是在所有的浏览器提供应polyfilled。另一个不好的事情是,缩小的功能将不保存其原来的名称。

那岂不是巨大的注释就其定义与 Foo.name ='富'函数,并坚持pre-取得的财产?不是真的。 Function.name 是<一个href=\"https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Browser_compatibility\"相对=nofollow>原本不可配置的,所以它是只读的在浏览器中的太多了。

如果您不打算回避最小化所有,或者你不太喜欢配置minifier至preserve类名(按设计故障的解决方案),不要使用 Function.name 对于这样的事情。

在角扩展ES6 / TS类典型的例子是

 出口类Foo {
  静态_name ='富';
}出口默认angular.module('app.foo',[])
  .factory('富',富)
  //如果DRY是必须的,
  // .factory(Foo._name,富)
  。名称;


 进口{}富从'./foo';出口类酒吧扩展美孚{
  静态_name ='吧';
}。出口默认angular.module('app.bar',[])工厂('酒吧',酒吧)。名称;


 从./foo'进口moduleFoo;
进口moduleBar从'./bar';angular.module('应用',[moduleFoo,moduleBar]);

因此​​出口角模块和类应该齐头并进,它们是不可互换。

I am trying to build a generic repository using:

  • Typescript
  • ES6
  • Angular 1.x

But I can't figure out how I should inject the Entity and then get its module name.

The reason why i want to get the name: Is because i follow a naming convention where a file called order-count.ts should render the URL '/order/count'

Is this solvable with Typescript/Javascript?

Here is what i have:

order-module.ts

import {App} from '../../App';
import {OrderService} from './order-service';

const module: ng.IModule = App.module('app.order', []);

module.service('orderService', OrderService);

order-service.ts

import {CrudService} from '../../shared/services/crud-service'
import {OrderCount} from '../order/entities/order-count';

export class OrderService {
    // @ngInject
    constructor(private crudService: CrudService<OrderCount>) {
        this.crudService = crudService;
    }

    getOrders() {
        var promise = this.crudService.getAll();

        promise.then(response => {
            console.log(response, 'success');
        }, error => {
            console.log(error, 'failed');
        });
    }
}

order-count.ts

import {Entity} from '../../../shared/models/entity';

export class OrderCount extends Entity {
    storeId: string;
    storeName: string;
}

entity.ts

export interface IEntity {
    id: number;
}

entity.ts

import {IEntity} from '../../module/contracts/entities/entity';

export class Entity implements IEntity {
    new() { }
    id: number;
}

crud-service.ts

'use strict';
import { Entity } from '../models/entity';
import { EndpointService } from './endpointService';

export class CrudService<TEntity extends Entity> {
    private baseCallPath: string;
    private entity: { new (): Entity };

    // @ngInject
    constructor(private endpointService: EndpointService, private $http: ng.IHttpService) {
        this.baseCallPath = new this.entity().constructor.name.replace('-', '/');
    }

    getAll(): ng.IHttpPromise<any> {
        return this.handleResponse(
            this.$http.get(this.endpointService.getUrl(this.baseCallPath)),
            'getAll'
        );
    }

    handleResponse(promise: ng.IHttpPromise<any>, callerMethodName: string): ng.IHttpPromise<any> {
        return promise.success((data: any) => {
            Array.prototype.push.apply(this.baseCallPath, data);
        }).error((reason: any) => {
            console.log(this.baseCallPath + callerMethodName, 'ERROR', reason);
        });
    }
}

endpoint-service.ts

export class EndpointService {
    private baseUri: string = 'http://localhost:3000/api/';

    getUrl(moduleName: string): string {
        return this.baseUri + moduleName;
    }
}

解决方案

Regarding the usage of class name as a value you may check this relevant question.

The good thing it can be retrieved and used as Foo.name or this.constructor.name. The bad thing is that it isn't available in every browser and should be polyfilled. Another bad thing is that minified function won't save its original name.

Wouldn't it be great to annotate function with Foo.name = 'Foo' on its definition and stick to pre-made property? Not really. Function.name is originally non-configurable, so it is read-only in a plethora of browsers.

If you don't plan to avoid minimization at all, or you're not too fond of configuring minifier to preserve class names (a solution faulty by design), don't use Function.name for anything like that.

The typical case for extendable ES6/TS class in Angular is

export class Foo {
  static _name = 'Foo';
}

export default angular.module('app.foo', [])
  .factory('Foo', Foo)
  // if DRY is a must,
  // .factory(Foo._name, Foo)
  .name;


import { Foo } from './foo';

export class Bar extends Foo {
  static _name = 'Bar';
}

export default angular.module('app.bar', []).factory('Bar', Bar).name;


import moduleFoo from './foo';
import moduleBar from './bar';

angular.module('app', [moduleFoo, moduleBar]);

So exports for Angular modules and classes should go hand in hand, they are not interchangeable.

这篇关于打字稿:注入通用&安培;获得ES6模块名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆