UNPKG

25.2 kBTypeScriptView Raw
1/** @publicapi @module ng1 */ /** */
2import { StateDeclaration, _ViewDeclaration, IInjectable, Transition, HookResult } from '@uirouter/core';
3/**
4 * The signature for Angular 1 State Transition Hooks.
5 *
6 * State hooks are registered as onEnter/onRetain/onExit in state declarations.
7 * State hooks can additionally be injected with $transition$ and $state$ for
8 * the current [[Transition]] and [[StateObject]] in the transition.
9 *
10 * Transition State Hooks are callback functions that hook into the lifecycle events of specific states during a transition.
11 * As a transition runs, it may exit some states, retain (keep) states, and enter states.
12 * As each lifecycle event occurs, the hooks which are registered for the event and that state are called (in priority order).
13 *
14 * #### See also:
15 *
16 * - [[IHookRegistry.onExit]]
17 * - [[IHookRegistry.onRetain]]
18 * - [[IHookRegistry.onEnter]]
19 *
20 * #### Example:
21 * ```js
22 * onEnter: function() { console.log('Entering'); }
23 * ```
24 *
25 * Not minification-safe
26 * ```js
27 * onRetain: function($state$) { console.log('Retained ' + $state$.name); }
28 * ```
29 *
30 * Annotated for minification-safety
31 * ```js
32 * onExit: [ '$transition$', '$state', function($transition$, $state) {
33 * // always redirect to 'foo' state when being exited
34 * if ($transition$.to().name !== 'foo') {
35 * return $state.target('foo');
36 * }
37 * } ]
38 * ```
39 *
40 * @returns an optional [[HookResult]] which may alter the transition
41 */
42export interface Ng1StateTransitionHook {
43 (...injectables: any[]): HookResult;
44}
45/**
46 * @internalapi
47 * an intermediate interface.
48 *
49 * Used to reset [[StateDeclaration]] typings to `any` so the [[Ng1StateDeclaration]] interface can then narrow them */
50export interface _Ng1StateDeclaration extends StateDeclaration {
51 onExit?: any;
52 onRetain?: any;
53 onEnter?: any;
54 views?: any;
55}
56/**
57 * The StateDeclaration object is used to define a state or nested state.
58 * It should be registered with the [[StateRegistry]].
59 *
60 * #### Example:
61 * ```js
62 * // StateDeclaration object
63 * var foldersState = {
64 * name: 'folders',
65 * url: '/folders',
66 * resolve: {
67 * allfolders: function(FolderService) {
68 * return FolderService.list();
69 * }
70 * },
71 * template: "<ul><li ng-repeat='folder in allfolders'>{{folder.name}}</li></ul>",
72 * controller: function(allfolders, $scope) {
73 * $scope.allfolders = allfolders;
74 * }
75 * }
76 * ```
77 *
78 * Since this interface extends [[Ng1ViewDeclaration]], any view declaration properties can be set directly
79 * on the state declaration and they will be applied to the view with the name `$default`. For example:
80 *
81 * ```js
82 * var state = {
83 * name: 'foo',
84 * url: '/foo',
85 * template: '<h1>foo</h1>',
86 * controller: 'FooController'
87 * }
88 * ```
89 *
90 * is simply syntactic sugar for:
91 *
92 * ```js
93 * var state = {
94 * name: 'foo',
95 * url: '/foo',
96 * views: {
97 * $default: {
98 * template: '<h1>foo</h1>',
99 * controller: 'FooController'
100 * }
101 * }
102 * }
103 * ```
104 *
105 * If a state definition contains a `views:` object, any view properties set directly on the state are ignored.
106 * Thus, this is an invalid state defintion:
107 *
108 * ```js
109 * var state = {
110 * name: 'foo',
111 * url: '/foo',
112 * controller: 'FooController', // invalid because views: exists
113 * views: {
114 * header: {
115 * template: '<h1>header</h1>'
116 * }
117 * }
118 * }
119 * ```
120 */
121export interface Ng1StateDeclaration extends _Ng1StateDeclaration, Ng1ViewDeclaration {
122 /**
123 * An optional object which defines multiple named views.
124 *
125 * Each key is the name of a view, and each value is a [[Ng1ViewDeclaration]].
126 * Unnamed views are internally renamed to `$default`.
127 *
128 * A view's name is used to match an active `<ui-view>` directive in the DOM. When the state
129 * is entered, the state's views are activated and matched with active `<ui-view>` directives:
130 *
131 * - The view's name is processed into a ui-view target:
132 * - ui-view address: an address to a ui-view
133 * - state anchor: the state to anchor the address to
134 *
135 * Examples:
136 *
137 * Targets three named ui-views in the parent state's template
138 *
139 * #### Example:
140 * ```js
141 * views: {
142 * header: {
143 * controller: "headerCtrl",
144 * templateUrl: "header.html"
145 * },
146 * body: {
147 * controller: "bodyCtrl",
148 * templateUrl: "body.html"
149 * },
150 * footer: "footerComponent"
151 * }
152 * ```
153 *
154 * #### Example:
155 * ```js
156 * // Targets named ui-view="header" in the template of the ancestor state 'top'
157 * // and the named `ui-view="body" from the parent state's template.
158 * views: {
159 * 'header@top': {
160 * controller: "msgHeaderCtrl",
161 * templateUrl: "msgHeader.html"
162 * },
163 * 'body': {
164 * controller: "messagesCtrl",
165 * templateUrl: "messages.html"
166 * }
167 * }
168 * ```
169 *
170 * ## View targeting details
171 *
172 * There are a few styles of view addressing/targeting.
173 * The most common is a simple `ui-view` name
174 *
175 * #### Simple ui-view name
176 *
177 * Addresses without an `@` are anchored to the parent state.
178 *
179 * #### Example:
180 * ```js
181 * // target the `<div ui-view='foo'></div>` created in the parent state's view
182 * views: {
183 * foo: {...}
184 * }
185 * ```
186 *
187 * #### View name anchored to a state
188 *
189 * You can anchor the `ui-view` name to a specific state by including an `@`
190 *
191 * #### Example:
192 * targets the `<div ui-view='foo'></div>` which was created in a view owned by the state `bar.baz`
193 * ```js
194 * views: {
195 * 'foo@bar.baz': {...}
196 * }
197 * ```
198 *
199 * #### Absolute addressing
200 *
201 * You can address a `ui-view` absolutely, using dotted notation, by prefixing the address with a `!`.
202 * Dotted addresses traverse the hierarchy of `ui-view`s active in the DOM:
203 *
204 * #### Example:
205 * absolutely targets the `<div ui-view='nested'></div>`
206 * ... which was created in the unnamed/$default root `<ui-view></ui-view>`
207 * ```js
208 * views: {
209 * '!$default.nested': {...}
210 * }
211 * ```
212 *
213 * #### Relative addressing
214 *
215 * Absolute addressing is actually relative addressing, anchored to the unnamed root state (`""`).
216 * You can also use relative addressing anchored to *any state*, in order to target a target deeply nested `ui-views`:
217 * The `ui-view` is targeted relative to the anchored state by traversing the nested `ui-view` names.
218 *
219 * #### Example:
220 * targets the `<div ui-view='bar'></div>`
221 * ... which was created inside the
222 * `<div ui-view='foo'></div>`
223 * ... which was created inside the parent state's template.
224 * ```js
225 * views: {
226 * 'foo.bar': {...}
227 * }
228 * ```
229 *
230 * #### Example:
231 * targets the `<div ui-view='bar'></div>`
232 * ... which was created in `<div ui-view='foo'></div>`
233 * ... which was created in a template from the state `baz.qux`
234 * ```js
235 * views: {
236 * 'foo.bar@baz.qux': {...}
237 * }
238 * ```
239 *
240 * #### Example:
241 * a view can relatively target a named `ui-view` defined on an ancestor using `^` (meaning "parent")
242 * ```js
243 * views: {
244 * 'foo@^': {...}, // foo@(parent state) (same as simply 'foo')
245 * 'bar@^.^': {...}, // bar@(grandparent state)
246 * 'baz@^.^.^': {...}, // baz@(great-grandparent state)
247 * }
248 * ```
249 *
250 * For additional in-depth details about how `ui-view` addressing works, see the internal api [[ViewService.match]].
251 *
252 * ---
253 *
254 * ## State template+controller and `views:` incompatiblity
255 *
256 * If a state has a `views` object, any state-level view properties ([[Ng1ViewDeclaration]]) are ignored. Therefore,
257 * if _any view_ for a state is declared in the `views` object, then _all of the state's views_ must be defined in
258 * the `views` object. The state declaration must not have any of the following fields:
259 * - component
260 * - bindings
261 * - resolveAs
262 * - template
263 * - templateUrl
264 * - templateProvider
265 * - controller
266 * - controllerAs
267 * - controllerProvider
268 */
269 views?: {
270 [key: string]: string | Ng1ViewDeclaration;
271 };
272 /**
273 * A state hook invoked when a state is being entered.
274 *
275 * The hook can inject global services.
276 * It can also inject `$transition$` or `$state$` (from the current transition).
277 *
278 * ### Example:
279 * ```js
280 * $stateProvider.state({
281 * name: 'mystate',
282 * onEnter: (MyService, $transition$, $state$) => {
283 * return MyService.doSomething($state$.name, $transition$.params());
284 * }
285 * });
286 * ```
287 *
288 * #### Example:`
289 * ```js
290 * $stateProvider.state({
291 * name: 'mystate',
292 * onEnter: [ 'MyService', '$transition$', '$state$', function (MyService, $transition$, $state$) {
293 * return MyService.doSomething($state$.name, $transition$.params());
294 * } ]
295 * });
296 * ```
297 */
298 onEnter?: Ng1StateTransitionHook | IInjectable;
299 /**
300 * A state hook invoked when a state is being exited.
301 *
302 * The hook can inject global services.
303 * It can also inject `$transition$` or `$state$` (from the current transition).
304 *
305 * ### Example:
306 * ```js
307 * $stateProvider.state({
308 * name: 'mystate',
309 * onExit: (MyService, $transition$, $state$) => {
310 * return MyService.doSomething($state$.name, $transition$.params());
311 * }
312 * });
313 * ```
314 *
315 * #### Example:`
316 * ```js
317 * $stateProvider.state({
318 * name: 'mystate',
319 * onExit: [ 'MyService', '$transition$', '$state$', function (MyService, $transition$, $state$) {
320 * return MyService.doSomething($state$.name, $transition$.params());
321 * } ]
322 * });
323 * ```
324 */
325 onExit?: Ng1StateTransitionHook | IInjectable;
326 /**
327 * A state hook invoked when a state is being retained.
328 *
329 * The hook can inject global services.
330 * It can also inject `$transition$` or `$state$` (from the current transition).
331 *
332 * #### Example:
333 * ```js
334 * $stateProvider.state({
335 * name: 'mystate',
336 * onRetain: (MyService, $transition$, $state$) => {
337 * return MyService.doSomething($state$.name, $transition$.params());
338 * }
339 * });
340 * ```
341 *
342 * #### Example:`
343 * ```js
344 * $stateProvider.state({
345 * name: 'mystate',
346 * onRetain: [ 'MyService', '$transition$', '$state$', function (MyService, $transition$, $state$) {
347 * return MyService.doSomething($state$.name, $transition$.params());
348 * } ]
349 * });
350 * ```
351 */
352 onRetain?: Ng1StateTransitionHook | IInjectable;
353 /**
354 * Makes all search/query parameters `dynamic`
355 *
356 * ### Deprecation warning: use [[ParamDeclaration.dynamic]] instead
357 *
358 * @deprecated
359 */
360 reloadOnSearch?: boolean;
361}
362export interface Ng1ViewDeclaration extends _ViewDeclaration {
363 /**
364 * The name of the component to use for this view.
365 *
366 * A property of [[Ng1StateDeclaration]] or [[Ng1ViewDeclaration]]:
367 *
368 * The name of an [angular 1.5+ `.component()`](https://docs.angularjs.org/guide/component) (or directive with
369 * bindToController and/or scope declaration) which will be used for this view.
370 *
371 * Resolve data can be provided to the component via the component's `bindings` object (for 1.3+ directives, the
372 * `bindToController` is used; for other directives, the `scope` declaration is used). For each binding declared
373 * on the component, any resolve with the same name is set on the component's controller instance. The binding
374 * is provided to the component as a one-time-binding. In general, components should likewise declare their
375 * input bindings as [one-way ("&lt;")](https://docs.angularjs.org/api/ng/service/$compile#-scope-).
376 *
377 * Note: inside a "views:" block, a bare string `"foo"` is shorthand for `{ component: "foo" }`
378 *
379 * Note: Mapping from resolve names to component inputs may be specified using [[bindings]].
380 *
381 * #### Example:
382 * ```js
383 * .state('profile', {
384 * // Use the <my-profile></my-profile> component for the Unnamed view
385 * component: 'MyProfile',
386 * }
387 *
388 * .state('messages', {
389 * // use the <nav-bar></nav-bar> component for the view named 'header'
390 * // use the <message-list></message-list> component for the view named 'content'
391 * views: {
392 * header: { component: 'NavBar' },
393 * content: { component: 'MessageList' }
394 * }
395 * }
396 *
397 * .state('contacts', {
398 * // Inside a "views:" block, a bare string "NavBar" is shorthand for { component: "NavBar" }
399 * // use the <nav-bar></nav-bar> component for the view named 'header'
400 * // use the <contact-list></contact-list> component for the view named 'content'
401 * views: {
402 * header: 'NavBar',
403 * content: 'ContactList'
404 * }
405 * }
406 * ```
407 *
408 *
409 * Note: When using `component` to define a view, you may _not_ use any of: `template`, `templateUrl`,
410 * `templateProvider`, `controller`, `controllerProvider`, `controllerAs`.
411 *
412 *
413 * See also: Todd Motto's angular 1.3 and 1.4 [backport of .component()](https://github.com/toddmotto/angular-component)
414 */
415 component?: string;
416 /**
417 * An object which maps `resolve`s to [[component]] `bindings`.
418 *
419 * A property of [[Ng1StateDeclaration]] or [[Ng1ViewDeclaration]]:
420 *
421 * When using a [[component]] declaration (`component: 'myComponent'`), each input binding for the component is supplied
422 * data from a resolve of the same name, by default. You may supply data from a different resolve name by mapping it here.
423 *
424 * Each key in this object is the name of one of the component's input bindings.
425 * Each value is the name of the resolve that should be provided to that binding.
426 *
427 * Any component bindings that are omitted from this map get the default behavior of mapping to a resolve of the
428 * same name.
429 *
430 * #### Example:
431 * ```js
432 * $stateProvider.state('foo', {
433 * resolve: {
434 * foo: function(FooService) { return FooService.get(); },
435 * bar: function(BarService) { return BarService.get(); }
436 * },
437 * component: 'Baz',
438 * // The component's `baz` binding gets data from the `bar` resolve
439 * // The component's `foo` binding gets data from the `foo` resolve (default behavior)
440 * bindings: {
441 * baz: 'bar'
442 * }
443 * });
444 *
445 * app.component('Baz', {
446 * templateUrl: 'baz.html',
447 * controller: 'BazController',
448 * bindings: {
449 * foo: '<', // foo binding
450 * baz: '<' // baz binding
451 * }
452 * });
453 * ```
454 *
455 */
456 bindings?: {
457 [key: string]: string;
458 };
459 /**
460 * Dynamic component provider function.
461 *
462 * A property of [[Ng1StateDeclaration]] or [[Ng1ViewDeclaration]]:
463 *
464 * This is an injectable provider function which returns the name of the component to use.
465 * The provider will invoked during a Transition in which the view's state is entered.
466 * The provider is called after the resolve data is fetched.
467 *
468 * #### Example:
469 * ```js
470 * componentProvider: function(MyResolveData, $transition$) {
471 * if (MyResolveData.foo) {
472 * return "fooComponent"
473 * } else if ($transition$.to().name === 'bar') {
474 * return "barComponent";
475 * }
476 * }
477 * ```
478 */
479 componentProvider?: IInjectable;
480 /**
481 * The view's controller function or name
482 *
483 * A property of [[Ng1StateDeclaration]] or [[Ng1ViewDeclaration]]:
484 *
485 * The controller function, or the name of a registered controller. The controller function will be used
486 * to control the contents of the [[directives.uiView]] directive.
487 *
488 * If specified as a string, controllerAs can be declared here, i.e., "FooController as foo" instead of in
489 * a separate [[controllerAs]] property.
490 *
491 * See: [[Ng1Controller]] for information about component-level router hooks.
492 */
493 controller?: IInjectable | string;
494 /**
495 * A controller alias name.
496 *
497 * A property of [[Ng1StateDeclaration]] or [[Ng1ViewDeclaration]]:
498 *
499 * If present, the controller will be published to scope under the `controllerAs` name.
500 * See: https://docs.angularjs.org/api/ng/directive/ngController
501 */
502 controllerAs?: string;
503 /**
504 * Dynamic controller provider function.
505 *
506 * A property of [[Ng1StateDeclaration]] or [[Ng1ViewDeclaration]]:
507 *
508 * This is an injectable provider function which returns the actual controller function, or the name
509 * of a registered controller. The provider will invoked during a Transition in which the view's state is
510 * entered. The provider is called after the resolve data is fetched.
511 *
512 * #### Example:
513 * ```js
514 * controllerProvider: function(MyResolveData, $transition$) {
515 * if (MyResolveData.foo) {
516 * return "FooCtrl"
517 * } else if ($transition$.to().name === 'bar') {
518 * return "BarCtrl";
519 * } else {
520 * return function($scope) {
521 * $scope.baz = "Qux";
522 * }
523 * }
524 * }
525 * ```
526 */
527 controllerProvider?: IInjectable;
528 /**
529 * The scope variable name to use for resolve data.
530 *
531 * A property of [[Ng1StateDeclaration]] or [[Ng1ViewDeclaration]]:
532 *
533 * When a view is activated, the resolved data for the state which the view belongs to is put on the scope.
534 * This property sets the name of the scope variable to use for the resolved data.
535 *
536 * Defaults to `$resolve`.
537 */
538 resolveAs?: string;
539 /**
540 * The HTML template for the view.
541 *
542 * A property of [[Ng1StateDeclaration]] or [[Ng1ViewDeclaration]]:
543 *
544 * HTML template as a string, or a function which returns an html template as a string.
545 * This template will be used to render the corresponding [[directives.uiView]] directive.
546 *
547 * This property takes precedence over templateUrl.
548 *
549 * If `template` is a function, it will be called with the Transition parameters as the first argument.
550 *
551 * #### Example:
552 * ```js
553 * template: "<h1>inline template definition</h1><div ui-view></div>"
554 * ```
555 *
556 * #### Example:
557 * ```js
558 * template: function(params) {
559 * return "<h1>generated template</h1>";
560 * }
561 * ```
562 */
563 template?: Function | string;
564 /**
565 * The URL for the HTML template for the view.
566 *
567 * A property of [[Ng1StateDeclaration]] or [[Ng1ViewDeclaration]]:
568 *
569 * A path or a function that returns a path to an html template.
570 * The template will be fetched and used to render the corresponding [[directives.uiView]] directive.
571 *
572 * If `templateUrl` is a function, it will be called with the Transition parameters as the first argument.
573 *
574 * #### Example:
575 * ```js
576 * templateUrl: "/templates/home.html"
577 * ```
578 *
579 * #### Example:
580 * ```js
581 * templateUrl: function(params) {
582 * return myTemplates[params.pageId];
583 * }
584 * ```
585 */
586 templateUrl?: string | Function;
587 /**
588 * Injected function which returns the HTML template.
589 *
590 * A property of [[Ng1StateDeclaration]] or [[Ng1ViewDeclaration]]:
591 *
592 * Injected function which returns the HTML template.
593 * The template will be used to render the corresponding [[directives.uiView]] directive.
594 *
595 * #### Example:
596 * ```js
597 * templateProvider: function(MyTemplateService, $transition$) {
598 * return MyTemplateService.getTemplate($transition$.params().pageId);
599 * }
600 * ```
601 */
602 templateProvider?: IInjectable;
603}
604/**
605 * The shape of a controller for a view (and/or component), defining the controller callbacks.
606 *
607 * A view in UI-Router is comprised of either a `component` ([[Ng1ViewDeclaration.component]]) or a combination of a
608 * `template` (or `templateProvider`) and a `controller` (or `controllerProvider`).
609 *
610 * The `controller` object (or the `component`'s controller object) can define component-level controller callbacks,
611 * which UI-Router will call at the appropriate times. These callbacks are similar to Transition Hooks
612 * ([[IHookRegistry]]), but are only called if the view is currently active.
613 *
614 * This interface defines the UI-Router component callbacks.
615 *
616 */
617export interface Ng1Controller {
618 /** @hidden */
619 $onInit(): void;
620 /**
621 * This callback is called when parameter values have changed.
622 *
623 * This callback can be used to respond to changing parameter values in the current state, or in parent/child states.
624 * This callback is especially handy when using dynamic parameters ([[ParamDeclaration.dynamic]])
625 *
626 * Called when:
627 * - The view is still active
628 * - A new transition has completed successfully
629 * - The state for the view (controller) was not reloaded
630 * - At least one parameter value was changed
631 *
632 * Called with:
633 * @param newValues an object containing the changed parameter values
634 * @param $transition$ the new Transition which triggered this callback
635 *
636 * #### Example:
637 * ```js
638 * angular.module('foo').controller('FancyCtrl', function() {
639 * this.uiOnParamsChanged = function(newParams) {
640 * console.log("new params: ", newParams);
641 * }
642 * });
643 * ```
644 */
645 uiOnParamsChanged(newValues: any, $transition$: Transition): void;
646 /**
647 * This callback is called when the view's state is about to be exited.
648 *
649 * This callback is used to inform a view that it is about to be exited, due to a new [[Transition]].
650 * The callback can ask for user confirmation, and cancel or alter the new Transition. The callback should
651 * return a value, or a promise for a value. If a promise is returned, the new Transition waits until the
652 * promise settles.
653 *
654 *
655 * Called when:
656 * - The view is still active
657 * - A new Transition is about to run
658 * - The new Transition will exit the view's state
659 *
660 * Called with:
661 * - The new Transition
662 *
663 * Relevant return Values:
664 * - `false`: The transition is cancelled.
665 * - A rejected promise: The transition is cancelled.
666 * - [[TargetState]]: The transition is redirected to the new target state.
667 * - Anything else: the transition will continue normally (the state and view will be deactivated)
668 *
669 * #### Example:
670 * ```js
671 * app.component('myComponent', {
672 * template: '<input ng-model="$ctrl.data" type="text">',
673 * bindings: { 'data': '<' },
674 * controller: function() {
675 *
676 * this.originalData = angular.copy(this.data);
677 *
678 * this.uiCanExit = function() {
679 * if (!angular.equals(this.data, this.originalData)) {
680 * // Note: This could also return a Promise and request async
681 * // confirmation using something like ui-bootstrap $modal
682 * return window.confirm("Data has changed. Exit anyway and lose changes?");
683 * }
684 * }
685 * }
686 * }
687 * ```
688 *
689 * @param transition the new Transition that is about to exit the component's state
690 * @return a HookResult, or a promise for a HookResult
691 */
692 uiCanExit(transition: Transition): HookResult;
693}
694/**
695 * Manages which template-loading mechanism to use.
696 *
697 * Defaults to `$templateRequest` on Angular versions starting from 1.3, `$http` otherwise.
698 */
699export interface TemplateFactoryProvider {
700 /**
701 * Forces $templateFactory to use $http instead of $templateRequest.
702 *
703 * UI-Router uses `$templateRequest` by default on angular 1.3+.
704 * Use this method to choose to use `$http` instead.
705 *
706 * ---
707 *
708 * ## Security warning
709 *
710 * This might cause XSS, as $http doesn't enforce the regular security checks for
711 * templates that have been introduced in Angular 1.3.
712 *
713 * See the $sce documentation, section
714 * <a href="https://docs.angularjs.org/api/ng/service/$sce#impact-on-loading-templates">
715 * Impact on loading templates</a> for more details about this mechanism.
716 *
717 * *Note: forcing this to `false` on Angular 1.2.x will crash, because `$templateRequest` is not implemented.*
718 *
719 * @param useUnsafeHttpService `true` to use `$http` to fetch templates
720 */
721 useHttpService(useUnsafeHttpService: boolean): any;
722}
723declare module '@uirouter/core/lib/state/stateRegistry' {
724 interface StateRegistry {
725 register(state: Ng1StateDeclaration | {
726 new (): Ng1StateDeclaration;
727 }): any;
728 }
729}