Skip to content

Commit

Permalink
feat(view): A view without anything to render defaults to `<ui-view><…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
christopherthielen committed Nov 29, 2016
1 parent 37d6f9a commit 7d28fdd
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 6 deletions.
8 changes: 3 additions & 5 deletions src/ng1/statebuilders/views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ const hasAnyKey = (keys, obj) =>
* and applies the state-level configuration to a view named `$default`.
*/
export function ng1ViewsBuilder(state: State) {
// Do not process root state
if (!state.parent) return {};

let tplKeys = ['templateProvider', 'templateUrl', 'template', 'notify', 'async'],
ctrlKeys = ['controller', 'controllerProvider', 'controllerAs', 'resolveAs'],
compKeys = ['component', 'bindings', 'componentProvider'],
Expand All @@ -39,9 +42,7 @@ export function ng1ViewsBuilder(state: State) {
name = name || "$default";
// Account for views: { header: "headerComponent" }
if (isString(config)) config = { component: <string> config };
if (!Object.keys(config).length) return;

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

load() {
let $q = services.$q;
if (!this.hasTemplate())
throw new Error(`No template configuration specified for '${this.viewDecl.$uiViewName}@${this.viewDecl.$uiViewContextAnchor}'`);

let context = new ResolveContext(this.path);
let params = this.path.reduce((acc, node) => extend(acc, node.paramValues), {});

Expand Down
4 changes: 3 additions & 1 deletion src/ng1/templateFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ export class TemplateFactory {
* that string,or `null` if no template is configured.
*/
fromConfig(config: Ng1ViewDeclaration, params: any, context: ResolveContext) {
const defaultTemplate = "<ui-view></ui-view>";

return (
isDefined(config.template) ? this.fromString(config.template, params) :
isDefined(config.templateUrl) ? this.fromUrl(config.templateUrl, params) :
isDefined(config.templateProvider) ? this.fromProvider(config.templateProvider, params, context) :
isDefined(config.component) ? this.fromComponent(config.component, config.bindings) :
isDefined(config.componentProvider) ? this.fromComponentProvider(config.componentProvider, params, context) :
null
defaultTemplate
);
};

Expand Down
10 changes: 10 additions & 0 deletions test/viewDirectiveSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,16 @@ describe('uiView', function () {
expect($onInit).toHaveBeenCalled();
}));

it('should default the template to a <ui-view>', inject(function ($state, $q) {
$stateProvider.state('abstract', { abstract: true });
$stateProvider.state('abstract.foo', { template: 'hello' });
elem.append($compile('<div><ui-view></ui-view></div>')(scope));
$state.transitionTo('abstract.foo');
$q.flush();

expect(elem.text()).toBe('hello');
}));

describe('play nicely with other directives', function() {
// related to issue #857
it('should work with ngIf', inject(function ($state, $q, $compile) {
Expand Down

0 comments on commit 7d28fdd

Please sign in to comment.