Как я могу определить услугу AngularJS с помощью класса TypeScript, который не загрязняет глобальную область?
Я использую AngularJS и TypeScript. Я хочу реализовать службу AngularJS с помощью класса Typescript, например:
class HelloService {
public getWelcomeMessage():String {
return "Hello";
}
}
angular.module('app.services.helloService', []).factory('helloService', () => {
return new HelloService();
});
Скомпилируется следующий код javascript:
var HelloService = (function () {
function HelloService() {
}
HelloService.prototype.getWelcomeMessage = function () {
return "Hello";
};
return HelloService;
})();
angular.module('app.services.helloService', []).factory('helloService', function () {
return new HelloService();
});
Это загрязняет глобальное пространство имен переменной HelloService, чего я, очевидно, не хочу. (Используя консоль Chrome, я подтвердил, что HelloService был объектом.) Как я могу решить эту проблему или избежать этой проблемы?
Я пробовал очевидное:
angular.module('app.services.helloService', []).factory('helloService', function () {
class HelloService { ...}
return new HelloService();
});
но это дает мне ошибку компиляции ( "Непредвиденный токен, выражение" ожидается ".).
Одним из возможных решений, о которых я могу думать, является использование Typescript импорта и экспорта как-то, что, в свою очередь, будет использовать RequireJS. Вероятно, это приведет к завершению HelloService в функции определения, что позволит избежать загрязнения глобальной области с помощью HelloService. Тем не менее, я не хочу использовать RequireJS в своем приложении AngularJS, так как я думаю, что AngularJS достаточно хорош для моего использования, и это добавляет сложности.
Итак, мой вопрос: как я могу определить услугу AngularJS с помощью класса Typescript, который не загрязняет глобальную область?
Ответы
Ответ 1
Я должен предоставить то, что я на самом деле закончил:
module MyModule {
export class HelloService {
public getWelcomeMessage():String {
return "Hello";
}
}
angular.module('app.services.helloService', []).factory('helloService', () => {
return new HelloService();
});
}
Таким образом, я могу использовать
return new HelloService();
вместо
return new MyModule.HelloService();
Ответ 2
2016-05-06: Новый пример с использованием модулей в стиле ES6
Статический массив и конструктор $inject
остаются неизменными из предыдущего примера.
Единственное изменение - разбить классы на несколько файлов и использовать модули ES6 для определения определений классов.
/lib/HelloService.ts:
export class HelloService {
public getWelcomeMessage():String {
return "Hello from HelloService";
}
}
/lib/AnotherService.ts:
import {HelloService} from './HelloService';
/**
* Service that depends on HelloService.
*/
export class AnotherService {
// Define `HelloService` as a dependency.
static $inject = ['HelloService'];
constructor(
// Add the parameter and type definition.
public HelloService: HelloService
){}
public getWelcomeMessage():String {
// Access the service as: `this.HelloService`
// Enjoy auto-completion and type safety :)
var helloMsg = this.HelloService.getWelcomeMessage();
return "Welcome from AnotherService, " + helloMsg;
}
}
/index.ts:
// Using the services.
import {HelloService} from './lib/HelloService';
import {AnotherService} from './lib/AnotherService';
angular.module('HelloApp', [])
.service('HelloService', HelloService)
.service('AnotherService', AnotherService)
.run(['AnotherService', function(AnotherService: AnotherService){
console.log(AnotherService.getWelcomeMessage());
}]);
Предыдущий ответ: использование пространств имен
Создание из ответа Стив Фентона:
Чтобы разрешить инъекцию зависимостей, добавьте в свой класс статический массив $inject
.
См. Angular $инжекторная документация о том, как работает массив $inject
.
Зависимости будут вставляться в ваш конструктор в порядке, заданном массивом (и заставляет его работать с минимизацией).
Пример инъекции зависимостей:
namespace MyModule {
/**
* Angular Service
*/
export class HelloService {
public getWelcomeMessage():String {
return "Hello from HelloService";
}
}
/**
* Service that depends on HelloService.
*/
export class AnotherService {
// Define `HelloService` as a dependency.
static $inject = ['HelloService'];
constructor(
// Add the parameter and type definition.
public HelloService: MyModule.HelloService
){}
public getWelcomeMessage():String {
// Access the service as: `this.HelloService`
// Enjoy auto-completion and type safety :)
var helloMsg = this.HelloService.getWelcomeMessage();
return "Welcome from AnotherService, " + helloMsg;
}
}
}
// Using the services.
angular.module('app.services.helloService', [])
.service('HelloService', MyModule.HelloService)
.service('AnotherService', MyModule.AnotherService)
.run(['AnotherService', function(AnotherService: MyModule.AnotherService){
console.log(AnotherService.getWelcomeMessage());
}]);
Ответ 3
У меня есть два решения, первый дает вам синтаксис на основе классов, второй ничего не оставляет в глобальном масштабе...
Вы можете слегка скомпрометировать, добавив только один дескриптор в глобальную область (это действительно применимо, если у вас есть несколько классов, которые вы хотите избежать в глобальной области, так как в настоящее время у вас есть только один класс).
Следующий код оставляет только модуль в глобальной области.
module MyModule {
export class HelloService {
public getWelcomeMessage():String {
return "Hello";
}
}
export class AnotherService {
public getWelcomeMessage():String {
return "Hello";
}
}
}
angular.module('app.services.helloService', []).factory('helloService', () => {
return new MyModule.HelloService();
});
angular.module('app.services.anotherService', []).factory('anotherService', () => {
return new MyModule.AnotherService();
});
В качестве альтернативы, чтобы не оставить ни одной вещи в глобальной области, вы могли бы избежать синтаксиса класса и использовать "простой старый JavaScript":
angular.module('app.services.helloService', []).factory('helloService', () => {
var HelloService = (function () {
function HelloService() {
}
HelloService.prototype.getWelcomeMessage = function () {
return "Hello";
};
return HelloService;
})();
return new HelloService();
});
Ответ 4
Это метод, которым я следую:
module HelperServices {
export class helloService {
sayHelloWorld: () => string;
constructor() {
this.sayHelloWorld = () => {
return "Hello World";
}
}
}
}
Проще всего это.