Je veux écrire une classe TypeScript qui obtient un paramètre "préfixe" dans le constructeur. Cette classe doit également accéder à un inject LogService.
En utilisant du JavaScript simple, vous devriez le faire comme ceci:
angular.module('myModule', []).factory('LogWithPrefixFactory', ['LogService', function(LogService) {
var LogWithPrefixFactory = function(prefix) {
this.prefix = prefix;
}
LogWithPrefixFactory.prototype.log = function(txt) {
// we have access to the injected LogService
LogService.log(this.prefix, txt);
}
return LogWithPrefixFactory;
}]);
Ainsi, lorsque vous injectez cette fabrique dans un contrôleur, vous pouvez l’initialiser plusieurs fois de la manière suivante (inutile d’injecter LogService):
angular.module('myModule').controller('Ctrl', function(LogWithPrefixFactory) {
var foo = new LogWithPrefixFactory("My PREFIX");
var foo = new LogWithPrefixFactory("My OTHER PREFIX");
}
Comment définiriez-vous cette fabrique dans une classe TypeScript?.
Il y a au moins 2 options.
Première option, LogWithPrefixFactory
fournisse une méthode getInstance
qui renvoie le consignateur préfixé.
module services {
class LogService {
$window: any;
constructor($window: any) {
this.$window = $window;
}
log(prefix: string, txt: string) {
this.$window.alert(prefix + ' :: ' + txt);
}
}
angular.module('services').service('LogService', ['$window', LogService]);
export interface ILog {
log: (txt) => void;
}
export class LogWithPrefixFactory {
logService: LogService;
constructor(logService: LogService) {
this.logService = logService;
}
getInstance(prefix: string): ILog {
return {
log: (txt: string) => this.logService.log(prefix, txt);
}
}
}
angular.module('services').service('LogWithPrefixFactory', ['LogService', services.LogWithPrefixFactory]);
}
Ce qui peut être utilisé dans le contrôleur comme:
this.log1 = logWithPrefixFactory.getInstance("prefix1");
this.log2 = logWithPrefixFactory.getInstance("prefix2");
Plunker complet ici .
Deuxième option (semblable à une autre réponse), donnez Angular une autre fonction à utiliser en tant que constructeur, qui gère manuellement l'injection de constructeur LogService
(personnellement, je n'aime pas static
).
angular.module('services').service('LogWithPrefixFactory', ['LogService', function(logService) {
return function LogWithPrefixFactory(prefix) {
return new LogWithPrefix(prefix, logService);
};
}]);
Ce qui peut être utilisé dans le contrôleur comme:
this.log1 = new LogWithPrefixFactory("prefix1");
this.log2 = new LogWithPrefixFactory("prefix2");
ou même:
this.log1 = LogWithPrefixFactory("prefix1");
this.log2 = LogWithPrefixFactory("prefix2");
LogWithPrefixFactory
est injecté dans le contrôleur mais ce n'est pas le constructeur de la classe TypeScript, c'est la fonction intermédiaire qui renvoie l'instance réelle de la classe, après que celle-ci a été injectée "manuellement" avec LogService
.
Plunker complet ici .
Note: Ces boutons compilent de manière synchrone TypeScript sur le navigateur. Je l'ai testé uniquement sur Chrome. Aucune garantie qu'ils vont fonctionner. Enfin, j'ai ajouté manuellement une petite partie de angular.d.ts. Le fichier complet était très volumineux et mon proxy n'autorisait pas les gros POST.
Voici un moyen d'y parvenir:
class LogWithPrefixFactory {
static LogService;
constructor(prefix) {
this.prefix = prefix;
}
log = function(txt) {
// we have access to the injected LogService
LogService.log(this.prefix, txt);
}
}
angular.module('myModule', []).factory('LogWithPrefixFactory', ['LogService', function(LogService) {
LogWithPrefixFactory.LogService = LogService;
return LogWithPrefixFactory;
}]);
angular.module('myModule').controller('Ctrl', function(LogWithPrefixFactory) {
var foo = new LogWithPrefixFactory("My PREFIX");
var foo = new LogWithPrefixFactory("My OTHER PREFIX");
});
Rational: Vous voulez effectivement une propriété statique dans un LogWithPrefixFactory (à l'aide d'une fermeture dans JS), et vous voulez qu'elle vienne de Angular.
J'ai réalisé comme ci-dessous
module Dashboard {
export class LayoutServiceFactory {
static $inject = ["$q", "$http"];
private q: ng.IQService;
private http: ng.IHttpService;
constructor(private $q: ng.IQService, private $http: ng.IHttpService) {
this.q = $q;
this.http = $http;
}
getDataFromServer(serviceUrl) {
var deferred = this.q.defer();
this.http.get(serviceUrl, null)
.then(response => {
deferred.resolve((response) as any);
});
return deferred.promise;
}
static factory() {
var instance = ($q: ng.IQService, $http: ng.IHttpService) =>
new LayoutServiceFactory($q, $http);
return instance;
}
}
appModule.factory("LayoutService", LayoutServiceFactory.factory());
}
Cela a fonctionné pour moi.
namespace Services
{
export class MyService
{
constructor( protected $someService :any )
{
return this;
}
}
}
angular.module( 'myModule', [] ).factory( Services );
Vous pouvez créer un type qui vous permet de définir le constructeur de la fabrique:
// Defining the factory
// THIS IS THE IMPORTANT PART!!
export type SelectorFactory = new (config: any) => Selector;
export class Selector {
constructor(protected config: any, protected $http: ng.IHttpService) {
// do some stuff
}
}
angular.module('app')
.factory('Selector', ($http: ng.IHttpService) => {
// This is what the factory looks like to the end user
return (config: any) => {
return new Selector(config, $http);
};
});
// Using the factory
export class SampleCtrl {
constructor(public SelectorFactory: SelectorFactory) {
let config = { op: 1 };
let selector: Selector = new SelectorFactory(config);
}
}
voici comment je le fais
namespace app {
let app =angular.module('foo',[]);
app.factory(factories);//for registering whatever is there in factories namespace
}
namespace app.factories {
export class fooFactory {
static $inject = ['fooHelperService']
constructor(fooHelperService: services.fooHelperService) {
return {
fooFunc: () => {
return 'hellow world'
}
}
}
}
}