Skip to content

Commit 642df0b

Browse files
feat(decorators): Add state, resolve and resolve data decorators
1 parent 28ef1c5 commit 642df0b

File tree

5 files changed

+70
-0
lines changed

5 files changed

+70
-0
lines changed

src/decorators/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from "./resolveData";
2+
export * from "./resolve";
3+
export * from "./state";

src/decorators/resolve.ts

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* An ES7 decorator which maps resolve data to a component.
3+
*
4+
* Add this decorator to a property of your component.
5+
* The decorator marks the component's property to receive resolve data.
6+
*
7+
* When resolve data of the same name (token) is found,
8+
* the resolve data will be assigned to the component's property.
9+
*
10+
* #### Example:
11+
*
12+
* The component's properties receive resolve data from the state definition.
13+
* ```js
14+
* @Component({ selector: 'foo' })
15+
* export class FooComponent {
16+
* @Resolve() resolveToken1;
17+
* @Resolve('resolveToken2') prop2;
18+
* @Input() @Resolve() resolveToken3;
19+
* }
20+
*
21+
* const fooState = {
22+
* name: 'foo',
23+
* component: FooComponent,
24+
* resolve: [
25+
* { token: 'resolveToken1', deps: [], resolveFn: resolve1Fn },
26+
* { token: 'resolveToken2', deps: [], resolveFn: resolve2Fn },
27+
* { token: 'resolveToken3', deps: [], resolveFn: resolve3Fn },
28+
* ]
29+
* }
30+
* ```
31+
*
32+
* @param token The resolve token to bind to this property
33+
* (if omitted, the property name is used as the token)
34+
*/
35+
export function Resolve(token?: string): PropertyDecorator {
36+
return function(target, property) {
37+
const inputs = target['$inputs'] = target['$inputs'] || {};
38+
inputs[token] = property;
39+
};
40+
}

src/decorators/resolveData.ts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { StateDeclaration } from '../state/interface';
2+
import { isArray } from '../common/predicates';
3+
4+
export function ResolveData(resolveConfig: { token?: string, deps?: any[] }): PropertyDecorator {
5+
resolveConfig = resolveConfig || {};
6+
7+
return function(target: StateDeclaration, property) {
8+
const resolve = target.resolve = target.resolve || [];
9+
const token = resolveConfig.token || property;
10+
const deps = resolveConfig.deps || [];
11+
12+
if (!isArray(resolve)) {
13+
throw new Error(`@ResolveData() only supports array style resolve: state: '${target.name}', resolve: ${property}, token: ${token}.`)
14+
}
15+
16+
resolve.push({ token, deps, resolveFn: target[property] });
17+
};
18+
}

src/decorators/state.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { isString } from '../common/predicates';
2+
3+
export function State(stateName?: string): ClassDecorator {
4+
return function<T>(targetClass: { new(...args: any[]): T }) {
5+
if (isString(stateName)) targetClass.prototype.name = stateName;
6+
targetClass['__uiRouterState'] = true;
7+
};
8+
}

src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export * from "./state/index";
1111
export * from "./transition/index";
1212
export * from "./url/index";
1313
export * from "./view/index";
14+
export * from "./decorators/index";
1415
export * from "./globals";
1516

1617
export * from "./router";

0 commit comments

Comments
 (0)