Skip to content

Commit

Permalink
feat(decorators): Add state, resolve and resolve data decorators
Browse files Browse the repository at this point in the history
  • Loading branch information
christopherthielen committed Feb 23, 2017
1 parent 28ef1c5 commit 642df0b
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/decorators/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./resolveData";
export * from "./resolve";
export * from "./state";
40 changes: 40 additions & 0 deletions src/decorators/resolve.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* An ES7 decorator which maps resolve data to a component.
*
* Add this decorator to a property of your component.
* The decorator marks the component's property to receive resolve data.
*
* When resolve data of the same name (token) is found,
* the resolve data will be assigned to the component's property.
*
* #### Example:
*
* The component's properties receive resolve data from the state definition.
* ```js
* @Component({ selector: 'foo' })
* export class FooComponent {
* @Resolve() resolveToken1;
* @Resolve('resolveToken2') prop2;
* @Input() @Resolve() resolveToken3;
* }
*
* const fooState = {
* name: 'foo',
* component: FooComponent,
* resolve: [
* { token: 'resolveToken1', deps: [], resolveFn: resolve1Fn },
* { token: 'resolveToken2', deps: [], resolveFn: resolve2Fn },
* { token: 'resolveToken3', deps: [], resolveFn: resolve3Fn },
* ]
* }
* ```
*
* @param token The resolve token to bind to this property
* (if omitted, the property name is used as the token)
*/
export function Resolve(token?: string): PropertyDecorator {
return function(target, property) {
const inputs = target['$inputs'] = target['$inputs'] || {};
inputs[token] = property;
};
}
18 changes: 18 additions & 0 deletions src/decorators/resolveData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { StateDeclaration } from '../state/interface';
import { isArray } from '../common/predicates';

export function ResolveData(resolveConfig: { token?: string, deps?: any[] }): PropertyDecorator {
resolveConfig = resolveConfig || {};

return function(target: StateDeclaration, property) {
const resolve = target.resolve = target.resolve || [];
const token = resolveConfig.token || property;
const deps = resolveConfig.deps || [];

if (!isArray(resolve)) {
throw new Error(`@ResolveData() only supports array style resolve: state: '${target.name}', resolve: ${property}, token: ${token}.`)
}

resolve.push({ token, deps, resolveFn: target[property] });
};
}
8 changes: 8 additions & 0 deletions src/decorators/state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { isString } from '../common/predicates';

export function State(stateName?: string): ClassDecorator {
return function<T>(targetClass: { new(...args: any[]): T }) {
if (isString(stateName)) targetClass.prototype.name = stateName;
targetClass['__uiRouterState'] = true;
};
}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export * from "./state/index";
export * from "./transition/index";
export * from "./url/index";
export * from "./view/index";
export * from "./decorators/index";
export * from "./globals";

export * from "./router";
Expand Down

0 comments on commit 642df0b

Please sign in to comment.