A collection of angular 2 style decorators for angularjs 1.5.x projects written in typescript.
See example of usage here
angular-ts-decorators
tries to mimic angular 2 style decorators as closely as possible.
Some of the decorator interfaces (@Component and @Directive) were heavily inspired by this excellent Angular 1.x styleguide (ES2015).
Behind the scenes it uses Metadata Reflection API to add metadata to the classes.
npm i -S angular-ts-decorators
Dependencies: tslib
and reflect-metadata
Peer dependencies: "angular": ">=1.5.0"
Decorator | angularjs analog | Details |
---|---|---|
@NgModule | angular.module | |
@Injectable | angular.service | |
@Inject | --- | see @Inject for details |
@Component | angular.component | |
@Input | angular.component options binding ('<') | can be used only inside @Component decorator default input binding value can be overridden by passing parameter to the decorator |
@Output | angular.component options binding ('&') | can be used only inside @Component decorator |
@ViewParent | angular.component options require | pass controller name with syntax according to angularjs require spec |
@HostListener | --- | see @HostListener for details |
@ViewChild(ren) | --- | see @ViewChild for details |
@Directive | angular.directive | |
@Pipe | angular.filter |
Let's say we have a todo-form component from classical todo example with the following template
/* ----- todo/todo-form/todo-form.html ----- */
<form name="todoForm" ng-submit="$ctrl.onSubmit();">
<input type="text" ng-model="$ctrl.todo.title">
<button type="submit">Submit</button>
</form>
If we were writing in plain es6/typescript without decorators we'd define this component like this:
/* ----- todo/todo-form/todo-form.component.js ----- */
const templateUrl = require('./todo-form.html');
export const TodoFormComponent = {
bindings: {
todo: '<',
onAddTodo: '&'
},
templateUrl,
controller: class TodoFormComponent {
todo;
onAddTodo;
$onChanges(changes) {
if (changes.todo) {
this.todo = Object.assign({}, this.todo);
}
}
onSubmit() {
if (!this.todo.title) return;
this.onAddTodo({
$event: {
todo: this.todo
}
});
}
}
};
And then we'll register our component with angular like so:
import angular from 'angular';
import { TodoFormComponent } from './todo-form.component';
export const TodoFormModule = angular
.module('todo.form', [])
.component('todoForm', TodoFormComponent)
.name;
Using angular-ts-decorators
decorators in typescript the component code will look like this
/* ----- todo/todo-form/todo-form.component.ts ----- */
import { Component, Input, Output } from 'angular-ts-decorators';
const templateUrl = require('./todo-form.html');
@Component({
selector: 'todoForm',
templateUrl
})
export class TodoFormComponent implements OnChanges {
@Input() todo;
@Output() onAddTodo;
ngOnChanges(changes) {
if (changes.todo) {
this.todo = {...this.todo};
}
}
onSubmit() {
if (!this.todo.title) return;
this.onAddTodo({
$event: {
todo: this.todo
}
});
}
}
Notice how @Input and @Output decorators replace bindings of thecomponent, by default @Input correlates to '<' value of the bindingand @Output - to the '&' value, you can override bindings valuesonly in @Input decorator by passing '=' or '@' if you need to.
And we'll register it with angular like so:
/* ----- todo/todo-form/todo-form.module.ts ----- */
import { NgModule } from 'angular-ts-decorators';
import { TodoFormComponent } from './todo-form.component';
@NgModule({
declarations: [TodoFormComponent]
})
export class TodoFormModule {}
You should declare all of the components (@Component), directives (@Directive) and filters (@Pipe)you want to register with some module in
declarations
of @NgModule decorator, all of the services (@Injectable) and providers (also @Injectable with $get method) youshould declare asproviders
of @NgModule decorator, and all of the modules yourmodule depends on inimports
. Name of the class decoratedwith @NgModule is the name of the module you should provide inimports
of other module declaration that depends on this module.In addition you can define config and run blocks for your moduleby adding config and run methods to your module class declaration.
Here's an example of service using @Injectable decorator
/* ----- greeting/greeting.service.ts ----- */
import { Injectable } from 'angular-ts-decorators';
@Injectable()
export class GreetingService {
private greeting = 'Hello World!';
// Configuration function
public setGreeting(greeting: string) {
this.greeting = greeting;
}
}
Services, factories and constants can be registered using Angular 2 syntax by providing an array of provider objects. The provider object has a provide
property (string token), and a useClass
, useFactory
, or useValue
property to use as the provided value.
This is how angular filter looks like using angular 2 style @Pipe decorator:
/* ----- greeting/uppercase.filter.ts ----- */
import { Pipe, PipeTransform } from 'angular-ts-decorators';
@Pipe({name: 'uppercase'})
export class UppercasePipe implements PipeTransform {
public transform(item: string) {
return item.toUpperCase();
}
}
Please note, that using @Pipe decorator you can register only stateless filters, for stateful filters you need to fallback to original angularjs filter declaration
And here's an example of provider registration with @NgModule decorator, its configuration in config method of module class and it's usage in run method:
import { NgModule } from 'angular-ts-decorators';
import { TodoFormModule } from 'todo/todo-form/todo-form.module';
import { GreetingService } from 'greeting/greeting.service';
import { UppercasePipe } from 'greeting/uppercase.filter';
@NgModule({
id: 'AppModule',
imports: [
TodoFormModule
],
declarations: [UppercasePipe],
providers: [
GreetingService, // you can register this way only if you provide class name to @Injectable decorator
{provide: 'GreetingService', useClass: GreetingService},
{provide: 'GreetingServiceFactory', useFactory: () => new GreetingService()}
]
})
export class AppModule {
static config($compileProvider: ng.ICompileProvider) {
'ngInject';
$compileProvider.debugInfoEnabled(false);
}
static run(GreetingService: GreetingService) {
'ngInject';
console.log(GreetingService.getGreeting());
}
}
Please notice, that you can't define constructor and $injectanything into it, instead you need to specify all of the injections youwant to provide for your module config and run blocks using 'ngInject' comment inside those static methods respectively.
@HostListener is a special method decorator introduced in angular 2, see official docs
Please notice, that this feature is kind of experimental, because the way it's implemented is kind of hacky: classes that have @HostListener methods are replaced with a new class that extends the original class. It works with basic use cases, but there could be some implications in some edge cases, so be aware.
Usage:
import { HostListener } from 'angular-ts-decorators';
export class MyDirective {
@HostListener('click mouseover')
onClick() {
console.log('click');
}
}
The implementation of it in angularjs as follows, it injects $element into component constructor and attaches method decorated with @HostListener as event handler on $element in $postLink and dettaches it in $onDestroy:
export class MyDirective {
constructor(private $element: ng.IAugmentedJQuery) {}
$postLink() {
this.$element.on('click mouseover', this.onClick.bind(this));
}
$onDestroy() {
this.$element.off('click mouseover', this.onClick);
}
onClick() {
console.log('click');
}
}
@ViewChild and @ViewChildren are property decorators introduced in angular 2, see official docs
Usage is more or less the same as in official docs, but it doesn't support template variables obviously (cause they don't exist in angularjs).When provided selector is Component/Directive's type or selector, it's controller class is returned, if other css selector is provided - jqlite object is returned.
Please notice, that this feature is kind of experimental, because the way it's implemented is kind of hacky: classes that have @ViewChild properties are replaced with a new class that extends the original class. It works with basic use cases, but there could be some implications in some edge cases, so be aware.
@Inject decorator allows to inject providers under a different name, for example if you have a provider like this:
@Injectable('My.Service')
export class MyService {}
You can use it like this:
export class MyController {
constructor(@Inject('My.Service') service: MyService) {}
}
Please notice that this decorator relies on explicit annotations either using static $inject property or using tools like ngAnnotate
In angularjs the manual boostrap would look like this
angular.element(document).ready(() => {
angular.bootstrap(document, ['AppModule']);
});
With angular-ts-decorators
you can bootstrap your application using angular syntax
If your main module is a class decorated with NgModule metadata, you can bootstrap it like so:
platformBrowserDynamic().bootstrapModule(AppModule);
If your main module is registered using angularjs syntax exporting the module itself like so:
export const appModule = angular.module('AppModule', [(SomeModule as NgModule).module.name]);
or exporting only module name like so:
export const appModule = angular.module('AppModule', [(SomeModule as NgModule).module.name]).name;
Then you can bootstrap it by name like so:
platformBrowserDynamic().bootstrapModule(appModule);
or like so
platformBrowserDynamic().bootstrapModule('AppModule');
By default angularjs adds automatic function annotation for the application, you can override it by passing
{ strictDi: true }
as the second argument to bootstrapModule
在 Angular 2 Decorators - part 1 文章中,我们介绍了 TypeScript 中的四种装饰器。本文的主要目的是介绍 Angular 2 中常见的内置装饰器。Angular 2 内置装饰器分类: 类装饰器 @Component、@NgModule、@Pipe、@Injectable 属性装饰器 @Input、@Output、@ContentChild、@ContentCh
前端这个方向,对于新事物的接受能力和速度决定了你在整个行业的位置。 ng2还没有发布官方稳定版本,但是我觉得对于我来说这个时候是最好的蓄力时机,于是开始了ng2的学习之路。 接触ng2之前也接触过一个avalon的东西,但是不知道是不是哪里相克,就是不顺利,后来想想,都是大同小异,不如学学更具参考性的ng2. ng2支持typescript和es5,6开发,当然官方文档目前只有ts的,为了更快的上
唯一需要手动更改的包是到,我使用以下命令进行了更改: 然后,我将的所有导入语句更改为。 我现在在构建应用程序时收到以下错误:
Riak TS是专门面向时序数据处理的产品。它支持时序数据的快速写入和查询。此外,Riak TS的特性还包括:支持数据聚集和算术运算操作,通过Spark连接器与Apache Spark的集成,对Java、Erlang和Python等语言的客户端支持,基于标准SQL的查询系统。Riak TS 1.3 EE(企业版)是基于支持多集群复制的开源版本而构建。
Template project for setting up a TypeScript monorepo Table of content Features Setup Docs Examples ts-node Babel webpack jest create-react-app NextJS NestJS Features The main focus of this repo is ma
ts-app: Full-stack TypeScript Development Framework This project is a starting point for developing an API-first application using TypeScript, Node.js, and React. This project aims to support a "domai
koa+typescript 新项目,更加轻量,更加简单,请移步 lenneth 框架: koa+tyescript db: mongodb 编辑器: vscode 测试: mocha 项目地址: https://github.com/soraping/koa-ts.git 项目下载安装模块 git clone https://github.com/soraping/koa-ts.git
�� A starter for any TypeScript project meant to be published on NPM �� ts-ci is a project starter like TSDX or typescript-starter but (arguably) better because: It's not a CLI tool, the automation ha