Skip to content

Commit 012e228

Browse files
Merge pull request #63 from ui-router/beta5
Beta5
2 parents 7b70b4a + 2afda3e commit 012e228

File tree

11 files changed

+106
-47
lines changed

11 files changed

+106
-47
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "ui-router-ng2",
33
"description": "State-based routing for Angular 2",
4-
"version": "1.0.0-beta.4",
4+
"version": "1.0.0-beta.5",
55
"scripts": {
66
"clean": "shx rm -rf lib lib-esm _bundles _dec",
77
"compile": "npm run clean && ngc",
@@ -39,7 +39,7 @@
3939
"module": "lib/index.js",
4040
"typings": "lib/index.d.ts",
4141
"dependencies": {
42-
"ui-router-core": "=4.0.0",
42+
"ui-router-core": "=5.0.0",
4343
"ui-router-rx": "=0.2.1"
4444
},
4545
"peerDependencies": {

rollup.config.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ uglifyOpts.output.comments = (node, comment) =>
2222
comment.type === 'comment2' && /@license/i.test(comment.value);
2323

2424
let plugins = [
25-
nodeResolve({jsnext: true}),
25+
nodeResolve({ jsnext: true }),
2626
progress(),
2727
sourcemaps(),
2828
commonjs(),
@@ -41,9 +41,14 @@ function onwarn(warning) {
4141
}
4242

4343
function isExternal(id) {
44+
// ui-router-core and ui-router-rx should be external
4445
// All rxjs and @angular/* should be external
4546
// except for @angular/router/src/router_config_loader
46-
let externals = [ /^rxjs/, /^@angular\/(?!router\/src\/router_config_loader)/, ];
47+
let externals = [
48+
/^ui-router-(core|rx)/,
49+
/^rxjs/,
50+
/^@angular\/(?!router\/src\/router_config_loader)/,
51+
];
4752
return externals.map(regex => regex.exec(id)).reduce((acc, val) => acc || !!val, false);
4853
}
4954

@@ -89,6 +94,8 @@ const CONFIG = {
8994
'rxjs/operator/filter': 'Rx.Observable.prototype',
9095
'rxjs/operator/concatMap': 'Rx.Observable.prototype',
9196

97+
'ui-router-core': 'ui-router-core',
98+
'ui-router-rx': 'ui-router-rx',
9299
'@angular/core': 'ng.core',
93100
'@angular/common': 'ng.common',
94101
}

src/decorators/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./resolveData";

src/decorators/resolveData.ts

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

src/directives/uiSrefStatus.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { Directive, Output, EventEmitter, ContentChildren, QueryList } from '@angular/core';
44
import { UISref } from './uiSref';
55
import {
6-
PathNode, Transition, TargetState, State, anyTrueR, tail, unnestR, Predicate, UIRouterGlobals, Param, PathFactory
6+
PathNode, Transition, TargetState, StateObject, anyTrueR, tail, unnestR, Predicate, UIRouterGlobals, Param, PathFactory
77
} from 'ui-router-core';
88

99
import { Subscription } from 'rxjs/Subscription';
@@ -53,7 +53,7 @@ const inactiveStatus: SrefStatus = {
5353
*/
5454
const pathMatches = (target: TargetState): Predicate<PathNode[]> => {
5555
if (!target.exists()) return () => false;
56-
let state: State = target.$state();
56+
let state: StateObject = target.$state();
5757
let targetParamVals = target.params();
5858
let targetPath: PathNode[] = PathFactory.buildPath(target);
5959
let paramSchema: Param[] = targetPath.map(node => node.paramSchema)

src/directives/uiView.ts

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
1-
/** @ng2api @module directives */ /** */
1+
/** @ng2api @module directives */
2+
/** */
23
import {
3-
Component, ComponentFactoryResolver, ViewContainerRef, Input, ComponentRef, Type,
4-
ReflectiveInjector, ViewChild, Injector, Inject
4+
Component, ComponentFactoryResolver, ViewContainerRef, Input, ComponentRef, Type, ReflectiveInjector, ViewChild,
5+
Injector, Inject
56
} from '@angular/core';
6-
import {ReflectorReader, reflector} from '../private_import_core';
7-
7+
import { reflector } from '../private_import_core';
88
import {
9-
UIRouter, isFunction, Transition, parse, HookResult, TransitionHookFn, State, prop, StateDeclaration, inArray
10-
} from "ui-router-core";
11-
import {trace} from "ui-router-core";
12-
import {ViewContext, ViewConfig, ActiveUIView} from "ui-router-core";
13-
import {Ng2ViewConfig} from "../statebuilders/views";
14-
import {ResolveContext, NATIVE_INJECTOR_TOKEN} from "ui-router-core";
15-
import {flattenR} from "ui-router-core";
16-
import {MergeInjector} from "../mergeInjector";
17-
import { Subscription } from 'rxjs/Subscription';
9+
UIRouter, isFunction, Transition, parse, TransitionHookFn, StateDeclaration, inArray, trace, ViewContext, ViewConfig,
10+
ActiveUIView, ResolveContext, NATIVE_INJECTOR_TOKEN, flattenR
11+
} from 'ui-router-core';
12+
import { Ng2ViewConfig } from '../statebuilders/views';
13+
import { MergeInjector } from '../mergeInjector';
1814

1915
/** @hidden */
2016
let id = 0;
@@ -39,7 +35,7 @@ interface InputMapping {
3935
*
4036
* @internalapi
4137
*/
42-
const ng2ComponentInputs = (ng2CompClass: Type<any>) => {
38+
const ng2ComponentInputs = (ng2CompClass: Type<any>, component: any) => {
4339
/** Get "@Input('foo') _foo" inputs */
4440
let props = reflector.propMetadata(ng2CompClass);
4541
let _props = Object.keys(props || {})
@@ -61,7 +57,12 @@ const ng2ComponentInputs = (ng2CompClass: Type<any>) => {
6157
.reduce(flattenR, [])
6258
.map(input => ({ token: input, prop: input }));
6359

64-
return _props.concat(inputs) as InputMapping[];
60+
/** Get @ResolveData('foo') _foo" inputs */
61+
let __inputs = component.__inputs || {};
62+
let resolves = Object.keys(__inputs)
63+
.map(key => ({ token: key, prop: __inputs[key] }));
64+
65+
return _props.concat(inputs).concat(resolves) as InputMapping[];
6566
};
6667

6768
/**
@@ -282,15 +283,16 @@ export class UIView {
282283
* to the resolve data.
283284
*/
284285
applyInputBindings(ref: ComponentRef<any>, context: ResolveContext, componentClass) {
285-
let bindings = this.uiViewData.config.viewDecl['bindings'] || {};
286-
let explicitBoundProps = Object.keys(bindings);
286+
const component = ref.instance;
287+
const bindings = this.uiViewData.config.viewDecl['bindings'] || {};
288+
const explicitBoundProps = Object.keys(bindings);
287289

288290
// Supply resolve data to matching @Input('prop') or inputs: ['prop']
289-
let explicitInputTuples = explicitBoundProps
291+
const explicitInputTuples = explicitBoundProps
290292
.reduce((acc, key) => acc.concat([{ prop: key, token: bindings[key] }]), []);
291-
let implicitInputTuples = ng2ComponentInputs(componentClass)
292-
.filter(tuple => !inArray(explicitBoundProps, tuple.prop));
293293

294+
const implicitInputTuples = ng2ComponentInputs(componentClass, component)
295+
.filter(tuple => !inArray(explicitBoundProps, tuple.prop));
294296

295297
const addResolvable = (tuple: InputMapping) => ({
296298
prop: tuple.prop,
@@ -300,7 +302,7 @@ export class UIView {
300302
explicitInputTuples.concat(implicitInputTuples)
301303
.map(addResolvable)
302304
.filter(tuple => tuple.resolvable && tuple.resolvable.resolved)
303-
.forEach(tuple => { ref.instance[tuple.prop] = tuple.resolvable.data });
305+
.forEach(tuple => { component[tuple.prop] = tuple.resolvable.data });
304306

305307
// Initiate change detection for the newly created component
306308
ref.changeDetectorRef.detectChanges();

src/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
/** @ng2api @module ng2 */ /** for typedoc */
2-
export * from "ui-router-core";
2+
33
export * from "./interface";
4+
export * from "./decorators/index";
45
export * from "./providers";
56
export * from "./uiRouterNgModule";
67
export * from "./uiRouterConfig";
78
export * from "./directives/directives";
89
export * from "./statebuilders/views";
910
export * from "./lazyLoad/lazyLoadNgModule";
11+
12+
export * from "ui-router-core";

src/lazyLoad/lazyLoadNgModule.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
/** */
33
import { NgModuleRef, Injector, NgModuleFactory, Type, Compiler, NgModuleFactoryLoader } from "@angular/core";
44
import {
5-
Transition, LazyLoadResult, UIRouter, Resolvable, NATIVE_INJECTOR_TOKEN, isString, unnestR, inArray
5+
Transition, LazyLoadResult, UIRouter, Resolvable, NATIVE_INJECTOR_TOKEN, isString, unnestR, inArray, StateObject,
6+
uniqR
67
} from "ui-router-core";
7-
import { RootModule, UIROUTER_ROOT_MODULE, UIROUTER_MODULE_TOKEN } from "../uiRouterNgModule";
8+
import { RootModule, UIROUTER_ROOT_MODULE, UIROUTER_MODULE_TOKEN, StatesModule } from "../uiRouterNgModule";
89
import { applyModuleConfig } from "../uiRouterConfig";
910

1011
/**
@@ -143,14 +144,20 @@ export function applyNgModule(transition: Transition, ng2Module: NgModuleRef<any
143144
// Final name (without the .**)
144145
let replacementName = isFuture && isFuture[1];
145146

146-
let newRootModules: RootModule[] = multiProviderParentChildDelta(parentInjector, injector, UIROUTER_ROOT_MODULE);
147+
let newRootModules = multiProviderParentChildDelta(parentInjector, injector, UIROUTER_ROOT_MODULE)
148+
.reduce(uniqR, []) as RootModule[];
149+
let newChildModules= multiProviderParentChildDelta(parentInjector, injector, UIROUTER_MODULE_TOKEN)
150+
.reduce(uniqR, []) as StatesModule[];
151+
147152
if (newRootModules.length) {
148153
console.log(newRootModules);
149154
throw new Error('Lazy loaded modules should not contain a UIRouterModule.forRoot() module');
150155
}
151156

152-
let newChildModules: RootModule[] = multiProviderParentChildDelta(parentInjector, injector, UIROUTER_MODULE_TOKEN);
153-
newChildModules.forEach(module => applyModuleConfig(uiRouter, injector, module));
157+
let newStateObjects: StateObject[] = newChildModules
158+
.map(module => applyModuleConfig(uiRouter, injector, module))
159+
.reduce(unnestR, [])
160+
.reduce(uniqR, []);
154161

155162
let replacementState = registry.get(replacementName);
156163
if (!replacementState || replacementState === originalState) {
@@ -164,16 +171,11 @@ export function applyNgModule(transition: Transition, ng2Module: NgModuleRef<any
164171
// Supply the newly loaded states with the Injector from the lazy loaded NgModule.
165172
// If a tree of states is lazy loaded, only add the injector to the root of the lazy loaded tree.
166173
// The children will get the injector by resolve inheritance.
167-
let newStates = newChildModules.map(module => module.states)
168-
.reduce(unnestR, [])
169-
.map(state => state.$$state());
170-
171-
let newParentStates = newStates.filter(state => !inArray(newStates, state.parent));
174+
let newParentStates = newStateObjects.filter(state => !inArray(newStateObjects, state.parent));
172175

173176
// Add the Injector to the top of the lazy loaded state tree as a resolve
174177
newParentStates.forEach(state => state.resolvables.push(Resolvable.fromData(NATIVE_INJECTOR_TOKEN, injector)));
175178

176-
177179
return {};
178180
}
179181

src/statebuilders/lazyLoad.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/** @module ng2 */
22
/** */
33
import { LazyLoadResult, Transition, StateDeclaration } from "ui-router-core"; // has or is using
4-
import { BuilderFunction, State } from "ui-router-core";
4+
import { BuilderFunction, StateObject } from "ui-router-core";
55
import { loadNgModule } from "../lazyLoad/lazyLoadNgModule";
66

77
/**
@@ -47,7 +47,7 @@ import { loadNgModule } from "../lazyLoad/lazyLoadNgModule";
4747
* ```
4848
*
4949
*/
50-
export function ng2LazyLoadBuilder(state: State, parent: BuilderFunction) {
50+
export function ng2LazyLoadBuilder(state: StateObject, parent: BuilderFunction) {
5151
let loadNgModuleFn = state['loadChildren'];
5252
return loadNgModuleFn ? loadNgModule(loadNgModuleFn) : state.lazyLoad;
5353
}

src/statebuilders/views.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/** @module ng2 */ /** */
2-
import {State} from "ui-router-core";
2+
import {StateObject} from "ui-router-core";
33
import {PathNode} from "ui-router-core";
44
import {pick, forEach} from "ui-router-core";
55
import {ViewConfig} from "ui-router-core";
@@ -16,7 +16,7 @@ import {ViewService} from "ui-router-core";
1616
* If no `views: {}` property exists on the [[StateDeclaration]], then it creates the `views` object and
1717
* applies the state-level configuration to a view named `$default`.
1818
*/
19-
export function ng2ViewsBuilder(state: State) {
19+
export function ng2ViewsBuilder(state: StateObject) {
2020
let views: { [key: string]: Ng2ViewDeclaration } = {},
2121
viewsObject = state.views || {"$default": pick(state, ["component", "bindings"])};
2222

0 commit comments

Comments
 (0)