-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ui-router-ng2): Update providers and viewsBuilder to match new 1…
….0 API
- Loading branch information
1 parent
d42b617
commit ff54d61
Showing
9 changed files
with
383 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
|
||
import {UiSref} from "../ng2/uiSref"; | ||
import {UiSrefClass} from "../ng2/uiSrefActive"; | ||
import {UiView} from "../ng2/uiView"; | ||
export * from "./uiSref"; | ||
export * from "./uiSrefActive"; | ||
export * from "./uiView"; | ||
|
||
export let UIROUTER_DIRECTIVES = [UiSref, UiSrefClass, UiView]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,301 @@ | ||
/** @module ng2 */ /** */ | ||
import {_ViewDeclaration} from "../state/interface"; | ||
import {StateDeclaration, _ViewDeclaration} from "../state/interface"; | ||
import {ParamDeclaration} from "../params/interface"; | ||
import {IInjectable} from "../common/common"; | ||
import {Transition} from "../transition/transition"; | ||
import {Type} from "angular2/core"; | ||
|
||
/** | ||
* The StateDeclaration object is used to define a state or nested state. | ||
* It should be registered with the [[StateRegistry]]. | ||
* | ||
* @example | ||
* ```js | ||
* | ||
* import {FoldersComponent} from "./folders"; | ||
* | ||
* // StateDeclaration object | ||
* var foldersState = { | ||
* name: 'folders', | ||
* url: '/folders', | ||
* component: FoldersComponent, | ||
* resolve: { | ||
* allfolders: function(FolderService) { | ||
* return FolderService.list(); | ||
* } | ||
* } | ||
* } | ||
* ``` | ||
*/ | ||
export interface Ng2StateDeclaration extends StateDeclaration, Ng2ViewDeclaration { | ||
/** | ||
* An optional object used to define multiple named views. | ||
* | ||
* Each key is the name of a view, and each value is a [[Ng2ViewDeclaration]]. | ||
* Unnamed views are internally renamed to `$default`. | ||
* | ||
* A view's name is used to match an active `<ui-view>` directive in the DOM. When the state | ||
* is entered, the state's views are activated and then matched with active `<ui-view>` directives: | ||
* | ||
* - The view's name is processed into a ui-view target: | ||
* - ui-view address: an address to a ui-view | ||
* - state anchor: the state to anchor the address to | ||
* | ||
* Examples: | ||
* | ||
* Targets three named ui-views in the parent state's template | ||
* | ||
* @example | ||
* ```js | ||
* | ||
* views: { | ||
* header: HeaderComponent, | ||
* body: BodyComponent, | ||
* footer: FooterComponent | ||
* } | ||
* ``` | ||
* | ||
* @example | ||
* ```js | ||
* | ||
* // Targets named ui-view="header" in the template of the ancestor state 'top' | ||
* // and the named `ui-view="body" from the parent state's template. | ||
* views: { | ||
* 'header@top': MsgHeaderComponent, | ||
* 'body': MessagesComponent | ||
* } | ||
* ``` | ||
* | ||
* ## View targeting details | ||
* | ||
* There are a few styles of view addressing/targeting. The most common is a simple `ui-view` name | ||
* | ||
* | ||
* #### Simple ui-view name | ||
* | ||
* Addresses without an `@` are anchored to the parent state. | ||
* | ||
* @example | ||
* ```js | ||
* | ||
* // target the `<div ui-view='foo'></div>` created in the parent state's view | ||
* views: { foo: {...} } | ||
* ``` | ||
* | ||
* #### View name anchored to a state | ||
* | ||
* You can anchor the `ui-view` name to a specific state by including an `@` | ||
* | ||
* @example | ||
* | ||
* ```js | ||
* | ||
* // target the `<div ui-view='foo'></div>` which was created in a | ||
* // view owned by the state `bar.baz` | ||
* views: { 'foo@bar.baz': {...} } | ||
* ``` | ||
* | ||
* #### Absolute addressing | ||
* | ||
* You can address a `ui-view` absolutely, using dotted notation, by prefixing the address with a `!`. Dotted | ||
* addresses map to the hierarchy of `ui-view`s active in the DOM: | ||
* | ||
* @example | ||
* ```js | ||
* | ||
* // absolutely target the `<div ui-view='nested'></div>`... which was created | ||
* // in the unnamed/$default root `<ui-view></ui-view>` | ||
* views: { '!$default.nested': {...} } | ||
* ``` | ||
* | ||
* #### Relative addressing | ||
* | ||
* Absolute addressing is actually relative addressing, only anchored to the unnamed root state. You can also use | ||
* relative addressing anchored to any state, in order to target a target deeply nested `ui-views`: | ||
* | ||
* @example | ||
* ```js | ||
* | ||
* | ||
* // target the `<div ui-view='bar'></div>`... which was created inside the | ||
* // `<div ui-view='bar'></div>`... which was created inside the parent state's template. | ||
* views: { 'foo.bar': {...} } | ||
* ``` | ||
* | ||
* @example | ||
* ```js | ||
* | ||
* // target the `<div ui-view='bar'></div>`... which was created in | ||
* // `<div ui-view='foo'></div>`... which was created in a template crom the state `baz.qux` | ||
* views: { 'foo.bar@baz.qux': {...} } | ||
* | ||
* --- | ||
* | ||
* ## State `component:` and `views:` incompatiblity | ||
* | ||
* If a state has a `views` object, the state-level `component:` property is ignored. Therefore, | ||
* if _any view_ for a state is declared in the `views` object, then _all of the state's views_ must be defined in | ||
* the `views` object. | ||
*/ | ||
views?: { [key: string]: Ng2ViewDeclaration; }; | ||
} | ||
|
||
export interface Ng2ViewDeclaration extends _ViewDeclaration { | ||
component: Type; | ||
} | ||
/** | ||
* The class of the `Component` to use for this view. | ||
* | ||
* A property of [[Ng2StateDeclaration]] or [[Ng2ViewDeclaration]]: | ||
* | ||
* The component class which will be used for this view. | ||
* | ||
* Resolve data can be provided to the component using Dependency Injection. Currently, resolves must be injected | ||
* into the component using `@Inject('key')`, where `key` is the name of the resolve. | ||
* | ||
* TODO: document ng2 shorthand, like ng1's shorthand: inside a "views:" block, a bare string `"foo"` is shorthand for `{ component: "foo" }` | ||
* | ||
* @example | ||
* ```js | ||
* | ||
* .state('profile', { | ||
* // Use the <my-profile></my-profile> component for the Unnamed view | ||
* component: MyProfileComponent, | ||
* } | ||
* | ||
* .state('messages', { | ||
* // use the <nav-bar></nav-bar> component for the view named 'header' | ||
* // use the <message-list></message-list> component for the view named 'content' | ||
* views: { | ||
* header: { component: NavBar }, | ||
* content: { component: MessageList } | ||
* } | ||
* } | ||
* | ||
* .state('contacts', { | ||
* // Inside a "views:" block, supplying only a Component class is shorthand for { component: NavBar } | ||
* // use the <nav-bar></nav-bar> component for the view named 'header' | ||
* // use the <contact-list></contact-list> component for the view named 'content' | ||
* views: { | ||
* header: NavBar, | ||
* content: ContactList | ||
* } | ||
* } | ||
* ``` | ||
*/ | ||
component?: Type; | ||
|
||
/** | ||
* @hidden | ||
* | ||
* An object which maps `resolve`s to [[component]] `bindings`. | ||
* | ||
* A property of [[Ng2StateDeclaration]] or [[Ng2ViewDeclaration]]: | ||
* | ||
* When using a [[component]] declaration (`component: 'myComponent'`), each input binding for the component is supplied | ||
* data from a resolve of the same name, by default. You may supply data from a different resolve name by mapping it here. | ||
* | ||
* Each key in this object is the name of one of the component's input bindings. | ||
* Each value is the name of the resolve that should be provided to that binding. | ||
* | ||
* Any component bindings that are omitted from this map get the default behavior of mapping to a resolve of the | ||
* same name. | ||
* | ||
* @example | ||
* ```js | ||
* | ||
* $stateProvider.state('foo', { | ||
* resolve: { | ||
* foo: function(FooService) { return FooService.get(); }, | ||
* bar: function(BarService) { return BarService.get(); } | ||
* }, | ||
* component: 'Baz', | ||
* // The component's `baz` binding gets data from the `bar` resolve | ||
* // The component's `foo` binding gets data from the `foo` resolve (default behavior) | ||
* bindings: { | ||
* baz: 'bar' | ||
* } | ||
* }); | ||
* | ||
* app.component('Baz', { | ||
* templateUrl: 'baz.html', | ||
* controller: 'BazController', | ||
* bindings: { | ||
* foo: '<', // foo binding | ||
* baz: '<' // baz binding | ||
* } | ||
* }); | ||
* ``` | ||
* | ||
*/ | ||
// bindings?: { [key: string]: string }; | ||
} | ||
|
||
/** | ||
* The shape of a controller for a view (and/or component), defining the controller callbacks. | ||
* | ||
* A view in UI-Router is comprised of either a `component` ([[Ng2ViewDeclaration.component]]) or a combination of a | ||
* `template` (or `templateProvider`) and a `controller` (or `controllerProvider`). | ||
* | ||
* The `controller` object (or the `component`'s controller object) can define component-level controller callbacks, | ||
* which UI-Router will call at the appropriate times. These callbacks are similar to Transition Hooks | ||
* ([[IHookRegistry]]), but are only called if the view is currently active. | ||
* | ||
* This interface defines the UI-Router component callbacks. | ||
* | ||
* TODO: this should extend the ng2 Component interface | ||
*/ | ||
export interface Ng2Component { | ||
/** | ||
* This callback is called when parameter values have changed. | ||
* | ||
* This callback can be used to respond to changing parameter values in the current state, or in parent/child states. | ||
* This callback is especially handy when using dynamic parameters ([[ParamDeclaration.dynamic]]) | ||
* | ||
* Called when: | ||
* - The view is still active | ||
* - A new transition has completed successfully | ||
* - The state for the view (controller) was not reloaded | ||
* - At least one parameter value was changed | ||
* | ||
* Called with: | ||
* @param newValues an object containing the changed parameter values | ||
* @param $transition$ the new Transition which triggered this callback | ||
* | ||
* @example: | ||
* ```js | ||
* | ||
* angular.module('foo').controller('FancyCtrl', function() { | ||
* this.uiOnParamsChanged = function(newParams) { | ||
* console.log("new params: ", newParams); | ||
* } | ||
* }); | ||
* ``` | ||
*/ | ||
uiOnParamsChanged(newValues: any, $transition$: Transition); | ||
|
||
/** | ||
* This callback is called when the view's state is about to be exited. | ||
* | ||
* This callback is used to inform a view that it is about to be exited, due to a new [[Transition]]. | ||
* The callback can ask for user confirmation, and cancel or alter the new Transition. The callback should | ||
* return a value, or a promise for a value. If a promise is returned, the new Transition waits until the | ||
* promise settles. | ||
* | ||
* | ||
* Called when: | ||
* - The view is still active | ||
* - A new Transition is about to run | ||
* - The new Transition will exit the view's state | ||
* | ||
* Called with: | ||
* - This callback is injected in the new Transition's context | ||
* | ||
* Relevant return Values: | ||
* - `false`: The transition is cancelled. | ||
* - A rejected promise: The transition is cancelled. | ||
* - [[TargetState]]: The transition is redirected to the new target state. | ||
* - Anything else: the transition will continue normally (the state and view will be deactivated) | ||
* | ||
* @return a value, or a promise for a value. | ||
*/ | ||
uiCanExit(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import {Provider, provide} from "angular2/core"; | ||
import {UIRouter} from "../router"; | ||
import {Node} from "../path/node"; | ||
import {StateRegistry} from "../state/stateRegistry"; | ||
import {StateService} from "../state/stateService"; | ||
import {TransitionService} from "../transition/transitionService"; | ||
import {UrlMatcherFactory} from "../url/urlMatcherFactory"; | ||
import {UrlRouter} from "../url/urlRouter"; | ||
import {ViewService} from "../view/view"; | ||
import {UiView} from "./uiView"; | ||
import {ng2ViewsBuilder, Ng2ViewConfig} from "./viewsBuilder"; | ||
import {Ng2ViewDeclaration} from "./interface"; | ||
|
||
export const UIROUTER_PROVIDERS: Provider[] = [ | ||
|
||
provide(UIRouter, { useFactory: () => { | ||
let router = new UIRouter(); | ||
|
||
router.viewService.viewConfigFactory("ng2", (node: Node, config: Ng2ViewDeclaration) => new Ng2ViewConfig(node, config)); | ||
router.stateRegistry.decorator('views', ng2ViewsBuilder); | ||
router.stateRegistry.stateQueue.autoFlush(router.stateService); | ||
|
||
return router; | ||
} }), | ||
|
||
provide(StateService, { useFactory: (r: UIRouter) => { return r.stateService; }, deps: [UIRouter]}), | ||
|
||
provide(TransitionService, { useFactory: (r: UIRouter) => { return r.transitionService; }, deps: [UIRouter]}), | ||
|
||
provide(UrlMatcherFactory, { useFactory: (r: UIRouter) => { return r.urlMatcherFactory; }, deps: [UIRouter]}), | ||
|
||
provide(UrlRouter, { useFactory: (r: UIRouter) => { return r.urlRouter; }, deps: [UIRouter]}), | ||
|
||
provide(ViewService, { useFactory: (r: UIRouter) => { return r.viewService; }, deps: [UIRouter]}), | ||
|
||
provide(StateRegistry, { useFactory: (r: UIRouter) => { return r.stateRegistry; }, deps: [UIRouter]}), | ||
|
||
provide(UiView.INJECT.context, { useFactory: (r: StateRegistry) => { console.log(r); return r.root(); }, deps: [StateRegistry]} ), | ||
|
||
provide(UiView.INJECT.fqn, { useValue: null }) | ||
|
||
]; | ||
|
Oops, something went wrong.