Skip to content

Commit ff54d61

Browse files
feat(ui-router-ng2): Update providers and viewsBuilder to match new 1.0 API
1 parent d42b617 commit ff54d61

File tree

9 files changed

+383
-12
lines changed

9 files changed

+383
-12
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
},
4242
"license": "MIT",
4343
"devDependencies": {
44-
"angular2": "^2.0.0-beta.1",
44+
"angular2": "^2.0.0-beta.12",
4545
"babel-core": "^5.8.14",
4646
"conventional-changelog": "^1.1.0",
4747
"conventional-changelog-cli": "^1.1.1",

src/ng2.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55
/** for typedoc */
66

77
export * from "./core";
8-
98
import "./justjs";
109

11-
export * from "./ng2/uiView";
12-
export * from "./ng2/uiSref";
13-
export * from "./ng2/uiSrefActive";
10+
export * from "./ng2/providers";
11+
export * from "./ng2/directives";
1412

src/ng2/directives.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
import {UiSref} from "../ng2/uiSref";
3+
import {UiSrefClass} from "../ng2/uiSrefActive";
4+
import {UiView} from "../ng2/uiView";
5+
export * from "./uiSref";
6+
export * from "./uiSrefActive";
7+
export * from "./uiView";
8+
9+
export let UIROUTER_DIRECTIVES = [UiSref, UiSrefClass, UiView];

src/ng2/interface.ts

Lines changed: 297 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,301 @@
11
/** @module ng2 */ /** */
2-
import {_ViewDeclaration} from "../state/interface";
2+
import {StateDeclaration, _ViewDeclaration} from "../state/interface";
3+
import {ParamDeclaration} from "../params/interface";
4+
import {IInjectable} from "../common/common";
5+
import {Transition} from "../transition/transition";
36
import {Type} from "angular2/core";
47

8+
/**
9+
* The StateDeclaration object is used to define a state or nested state.
10+
* It should be registered with the [[StateRegistry]].
11+
*
12+
* @example
13+
* ```js
14+
*
15+
* import {FoldersComponent} from "./folders";
16+
*
17+
* // StateDeclaration object
18+
* var foldersState = {
19+
* name: 'folders',
20+
* url: '/folders',
21+
* component: FoldersComponent,
22+
* resolve: {
23+
* allfolders: function(FolderService) {
24+
* return FolderService.list();
25+
* }
26+
* }
27+
* }
28+
* ```
29+
*/
30+
export interface Ng2StateDeclaration extends StateDeclaration, Ng2ViewDeclaration {
31+
/**
32+
* An optional object used to define multiple named views.
33+
*
34+
* Each key is the name of a view, and each value is a [[Ng2ViewDeclaration]].
35+
* Unnamed views are internally renamed to `$default`.
36+
*
37+
* A view's name is used to match an active `<ui-view>` directive in the DOM. When the state
38+
* is entered, the state's views are activated and then matched with active `<ui-view>` directives:
39+
*
40+
* - The view's name is processed into a ui-view target:
41+
* - ui-view address: an address to a ui-view
42+
* - state anchor: the state to anchor the address to
43+
*
44+
* Examples:
45+
*
46+
* Targets three named ui-views in the parent state's template
47+
*
48+
* @example
49+
* ```js
50+
*
51+
* views: {
52+
* header: HeaderComponent,
53+
* body: BodyComponent,
54+
* footer: FooterComponent
55+
* }
56+
* ```
57+
*
58+
* @example
59+
* ```js
60+
*
61+
* // Targets named ui-view="header" in the template of the ancestor state 'top'
62+
* // and the named `ui-view="body" from the parent state's template.
63+
* views: {
64+
* 'header@top': MsgHeaderComponent,
65+
* 'body': MessagesComponent
66+
* }
67+
* ```
68+
*
69+
* ## View targeting details
70+
*
71+
* There are a few styles of view addressing/targeting. The most common is a simple `ui-view` name
72+
*
73+
*
74+
* #### Simple ui-view name
75+
*
76+
* Addresses without an `@` are anchored to the parent state.
77+
*
78+
* @example
79+
* ```js
80+
*
81+
* // target the `<div ui-view='foo'></div>` created in the parent state's view
82+
* views: { foo: {...} }
83+
* ```
84+
*
85+
* #### View name anchored to a state
86+
*
87+
* You can anchor the `ui-view` name to a specific state by including an `@`
88+
*
89+
* @example
90+
*
91+
* ```js
92+
*
93+
* // target the `<div ui-view='foo'></div>` which was created in a
94+
* // view owned by the state `bar.baz`
95+
* views: { 'foo@bar.baz': {...} }
96+
* ```
97+
*
98+
* #### Absolute addressing
99+
*
100+
* You can address a `ui-view` absolutely, using dotted notation, by prefixing the address with a `!`. Dotted
101+
* addresses map to the hierarchy of `ui-view`s active in the DOM:
102+
*
103+
* @example
104+
* ```js
105+
*
106+
* // absolutely target the `<div ui-view='nested'></div>`... which was created
107+
* // in the unnamed/$default root `<ui-view></ui-view>`
108+
* views: { '!$default.nested': {...} }
109+
* ```
110+
*
111+
* #### Relative addressing
112+
*
113+
* Absolute addressing is actually relative addressing, only anchored to the unnamed root state. You can also use
114+
* relative addressing anchored to any state, in order to target a target deeply nested `ui-views`:
115+
*
116+
* @example
117+
* ```js
118+
*
119+
*
120+
* // target the `<div ui-view='bar'></div>`... which was created inside the
121+
* // `<div ui-view='bar'></div>`... which was created inside the parent state's template.
122+
* views: { 'foo.bar': {...} }
123+
* ```
124+
*
125+
* @example
126+
* ```js
127+
*
128+
* // target the `<div ui-view='bar'></div>`... which was created in
129+
* // `<div ui-view='foo'></div>`... which was created in a template crom the state `baz.qux`
130+
* views: { 'foo.bar@baz.qux': {...} }
131+
*
132+
* ---
133+
*
134+
* ## State `component:` and `views:` incompatiblity
135+
*
136+
* If a state has a `views` object, the state-level `component:` property is ignored. Therefore,
137+
* if _any view_ for a state is declared in the `views` object, then _all of the state's views_ must be defined in
138+
* the `views` object.
139+
*/
140+
views?: { [key: string]: Ng2ViewDeclaration; };
141+
}
142+
5143
export interface Ng2ViewDeclaration extends _ViewDeclaration {
6-
component: Type;
7-
}
144+
/**
145+
* The class of the `Component` to use for this view.
146+
*
147+
* A property of [[Ng2StateDeclaration]] or [[Ng2ViewDeclaration]]:
148+
*
149+
* The component class which will be used for this view.
150+
*
151+
* Resolve data can be provided to the component using Dependency Injection. Currently, resolves must be injected
152+
* into the component using `@Inject('key')`, where `key` is the name of the resolve.
153+
*
154+
* TODO: document ng2 shorthand, like ng1's shorthand: inside a "views:" block, a bare string `"foo"` is shorthand for `{ component: "foo" }`
155+
*
156+
* @example
157+
* ```js
158+
*
159+
* .state('profile', {
160+
* // Use the <my-profile></my-profile> component for the Unnamed view
161+
* component: MyProfileComponent,
162+
* }
163+
*
164+
* .state('messages', {
165+
* // use the <nav-bar></nav-bar> component for the view named 'header'
166+
* // use the <message-list></message-list> component for the view named 'content'
167+
* views: {
168+
* header: { component: NavBar },
169+
* content: { component: MessageList }
170+
* }
171+
* }
172+
*
173+
* .state('contacts', {
174+
* // Inside a "views:" block, supplying only a Component class is shorthand for { component: NavBar }
175+
* // use the <nav-bar></nav-bar> component for the view named 'header'
176+
* // use the <contact-list></contact-list> component for the view named 'content'
177+
* views: {
178+
* header: NavBar,
179+
* content: ContactList
180+
* }
181+
* }
182+
* ```
183+
*/
184+
component?: Type;
185+
186+
/**
187+
* @hidden
188+
*
189+
* An object which maps `resolve`s to [[component]] `bindings`.
190+
*
191+
* A property of [[Ng2StateDeclaration]] or [[Ng2ViewDeclaration]]:
192+
*
193+
* When using a [[component]] declaration (`component: 'myComponent'`), each input binding for the component is supplied
194+
* data from a resolve of the same name, by default. You may supply data from a different resolve name by mapping it here.
195+
*
196+
* Each key in this object is the name of one of the component's input bindings.
197+
* Each value is the name of the resolve that should be provided to that binding.
198+
*
199+
* Any component bindings that are omitted from this map get the default behavior of mapping to a resolve of the
200+
* same name.
201+
*
202+
* @example
203+
* ```js
204+
*
205+
* $stateProvider.state('foo', {
206+
* resolve: {
207+
* foo: function(FooService) { return FooService.get(); },
208+
* bar: function(BarService) { return BarService.get(); }
209+
* },
210+
* component: 'Baz',
211+
* // The component's `baz` binding gets data from the `bar` resolve
212+
* // The component's `foo` binding gets data from the `foo` resolve (default behavior)
213+
* bindings: {
214+
* baz: 'bar'
215+
* }
216+
* });
217+
*
218+
* app.component('Baz', {
219+
* templateUrl: 'baz.html',
220+
* controller: 'BazController',
221+
* bindings: {
222+
* foo: '<', // foo binding
223+
* baz: '<' // baz binding
224+
* }
225+
* });
226+
* ```
227+
*
228+
*/
229+
// bindings?: { [key: string]: string };
230+
}
231+
232+
/**
233+
* The shape of a controller for a view (and/or component), defining the controller callbacks.
234+
*
235+
* A view in UI-Router is comprised of either a `component` ([[Ng2ViewDeclaration.component]]) or a combination of a
236+
* `template` (or `templateProvider`) and a `controller` (or `controllerProvider`).
237+
*
238+
* The `controller` object (or the `component`'s controller object) can define component-level controller callbacks,
239+
* which UI-Router will call at the appropriate times. These callbacks are similar to Transition Hooks
240+
* ([[IHookRegistry]]), but are only called if the view is currently active.
241+
*
242+
* This interface defines the UI-Router component callbacks.
243+
*
244+
* TODO: this should extend the ng2 Component interface
245+
*/
246+
export interface Ng2Component {
247+
/**
248+
* This callback is called when parameter values have changed.
249+
*
250+
* This callback can be used to respond to changing parameter values in the current state, or in parent/child states.
251+
* This callback is especially handy when using dynamic parameters ([[ParamDeclaration.dynamic]])
252+
*
253+
* Called when:
254+
* - The view is still active
255+
* - A new transition has completed successfully
256+
* - The state for the view (controller) was not reloaded
257+
* - At least one parameter value was changed
258+
*
259+
* Called with:
260+
* @param newValues an object containing the changed parameter values
261+
* @param $transition$ the new Transition which triggered this callback
262+
*
263+
* @example:
264+
* ```js
265+
*
266+
* angular.module('foo').controller('FancyCtrl', function() {
267+
* this.uiOnParamsChanged = function(newParams) {
268+
* console.log("new params: ", newParams);
269+
* }
270+
* });
271+
* ```
272+
*/
273+
uiOnParamsChanged(newValues: any, $transition$: Transition);
274+
275+
/**
276+
* This callback is called when the view's state is about to be exited.
277+
*
278+
* This callback is used to inform a view that it is about to be exited, due to a new [[Transition]].
279+
* The callback can ask for user confirmation, and cancel or alter the new Transition. The callback should
280+
* return a value, or a promise for a value. If a promise is returned, the new Transition waits until the
281+
* promise settles.
282+
*
283+
*
284+
* Called when:
285+
* - The view is still active
286+
* - A new Transition is about to run
287+
* - The new Transition will exit the view's state
288+
*
289+
* Called with:
290+
* - This callback is injected in the new Transition's context
291+
*
292+
* Relevant return Values:
293+
* - `false`: The transition is cancelled.
294+
* - A rejected promise: The transition is cancelled.
295+
* - [[TargetState]]: The transition is redirected to the new target state.
296+
* - Anything else: the transition will continue normally (the state and view will be deactivated)
297+
*
298+
* @return a value, or a promise for a value.
299+
*/
300+
uiCanExit();
301+
}

src/ng2/providers.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {Provider, provide} from "angular2/core";
2+
import {UIRouter} from "../router";
3+
import {Node} from "../path/node";
4+
import {StateRegistry} from "../state/stateRegistry";
5+
import {StateService} from "../state/stateService";
6+
import {TransitionService} from "../transition/transitionService";
7+
import {UrlMatcherFactory} from "../url/urlMatcherFactory";
8+
import {UrlRouter} from "../url/urlRouter";
9+
import {ViewService} from "../view/view";
10+
import {UiView} from "./uiView";
11+
import {ng2ViewsBuilder, Ng2ViewConfig} from "./viewsBuilder";
12+
import {Ng2ViewDeclaration} from "./interface";
13+
14+
export const UIROUTER_PROVIDERS: Provider[] = [
15+
16+
provide(UIRouter, { useFactory: () => {
17+
let router = new UIRouter();
18+
19+
router.viewService.viewConfigFactory("ng2", (node: Node, config: Ng2ViewDeclaration) => new Ng2ViewConfig(node, config));
20+
router.stateRegistry.decorator('views', ng2ViewsBuilder);
21+
router.stateRegistry.stateQueue.autoFlush(router.stateService);
22+
23+
return router;
24+
} }),
25+
26+
provide(StateService, { useFactory: (r: UIRouter) => { return r.stateService; }, deps: [UIRouter]}),
27+
28+
provide(TransitionService, { useFactory: (r: UIRouter) => { return r.transitionService; }, deps: [UIRouter]}),
29+
30+
provide(UrlMatcherFactory, { useFactory: (r: UIRouter) => { return r.urlMatcherFactory; }, deps: [UIRouter]}),
31+
32+
provide(UrlRouter, { useFactory: (r: UIRouter) => { return r.urlRouter; }, deps: [UIRouter]}),
33+
34+
provide(ViewService, { useFactory: (r: UIRouter) => { return r.viewService; }, deps: [UIRouter]}),
35+
36+
provide(StateRegistry, { useFactory: (r: UIRouter) => { return r.stateRegistry; }, deps: [UIRouter]}),
37+
38+
provide(UiView.INJECT.context, { useFactory: (r: StateRegistry) => { console.log(r); return r.root(); }, deps: [StateRegistry]} ),
39+
40+
provide(UiView.INJECT.fqn, { useValue: null })
41+
42+
];
43+

0 commit comments

Comments
 (0)