Skip to content

Commit 7d28fdd

Browse files
feat(view): A view without anything to render defaults to <ui-view></ui-view>
- If a view has no `template`, `templateUrl`, `templateProvider`, `component`, `componentProvider` then the default is a passthrough `ui-view` - This also applies to states without any of those properties; a default view is created with `ui-view` passthrough Closes #3178
1 parent 37d6f9a commit 7d28fdd

File tree

3 files changed

+16
-6
lines changed

3 files changed

+16
-6
lines changed

src/ng1/statebuilders/views.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ const hasAnyKey = (keys, obj) =>
2525
* and applies the state-level configuration to a view named `$default`.
2626
*/
2727
export function ng1ViewsBuilder(state: State) {
28+
// Do not process root state
29+
if (!state.parent) return {};
30+
2831
let tplKeys = ['templateProvider', 'templateUrl', 'template', 'notify', 'async'],
2932
ctrlKeys = ['controller', 'controllerProvider', 'controllerAs', 'resolveAs'],
3033
compKeys = ['component', 'bindings', 'componentProvider'],
@@ -39,9 +42,7 @@ export function ng1ViewsBuilder(state: State) {
3942
name = name || "$default";
4043
// Account for views: { header: "headerComponent" }
4144
if (isString(config)) config = { component: <string> config };
42-
if (!Object.keys(config).length) return;
4345

44-
// Configure this view for routing to an angular 1.5+ style .component (or any directive, really)
4546
if (hasAnyKey(compKeys, config) && hasAnyKey(nonCompKeys, config)) {
4647
throw new Error(`Cannot combine: ${compKeys.join("|")} with: ${nonCompKeys.join("|")} in stateview: '${name}@${state.name}'`);
4748
}
@@ -73,9 +74,6 @@ export class Ng1ViewConfig implements ViewConfig {
7374

7475
load() {
7576
let $q = services.$q;
76-
if (!this.hasTemplate())
77-
throw new Error(`No template configuration specified for '${this.viewDecl.$uiViewName}@${this.viewDecl.$uiViewContextAnchor}'`);
78-
7977
let context = new ResolveContext(this.path);
8078
let params = this.path.reduce((acc, node) => extend(acc, node.paramValues), {});
8179

src/ng1/templateFactory.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ export class TemplateFactory {
2323
* that string,or `null` if no template is configured.
2424
*/
2525
fromConfig(config: Ng1ViewDeclaration, params: any, context: ResolveContext) {
26+
const defaultTemplate = "<ui-view></ui-view>";
27+
2628
return (
2729
isDefined(config.template) ? this.fromString(config.template, params) :
2830
isDefined(config.templateUrl) ? this.fromUrl(config.templateUrl, params) :
2931
isDefined(config.templateProvider) ? this.fromProvider(config.templateProvider, params, context) :
3032
isDefined(config.component) ? this.fromComponent(config.component, config.bindings) :
3133
isDefined(config.componentProvider) ? this.fromComponentProvider(config.componentProvider, params, context) :
32-
null
34+
defaultTemplate
3335
);
3436
};
3537

test/viewDirectiveSpec.js

+10
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,16 @@ describe('uiView', function () {
431431
expect($onInit).toHaveBeenCalled();
432432
}));
433433

434+
it('should default the template to a <ui-view>', inject(function ($state, $q) {
435+
$stateProvider.state('abstract', { abstract: true });
436+
$stateProvider.state('abstract.foo', { template: 'hello' });
437+
elem.append($compile('<div><ui-view></ui-view></div>')(scope));
438+
$state.transitionTo('abstract.foo');
439+
$q.flush();
440+
441+
expect(elem.text()).toBe('hello');
442+
}));
443+
434444
describe('play nicely with other directives', function() {
435445
// related to issue #857
436446
it('should work with ngIf', inject(function ($state, $q, $compile) {

0 commit comments

Comments
 (0)