Skip to content

Commit

Permalink
refactor(viewService): only match ViewConfigs with ui-views of same $…
Browse files Browse the repository at this point in the history
…type

- This allows ng1 and ng2 views to be registered at the same time for the same 'uiViewName@context'
- Allow ViewConfigFactory to return an array of ViewConfigs
closes #2685
  • Loading branch information
christopherthielen committed Apr 11, 2016
1 parent 9111727 commit cdf1d19
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 12 deletions.
2 changes: 2 additions & 0 deletions src/ng1/viewDirective.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ function $ViewDirective( $view, $animate, $uiViewScroll, $interpolate,
name = $interpolate(attrs.uiView || attrs.name || '')(scope) || '$default';

let activeUIView: ActiveUIView = {
$type: 'ng1',
id: directive.count++, // Global sequential ID for ui-view tags added to DOM
name: name, // ui-view name (<div ui-view="name"></div>
fqn: inherited.$uiView.fqn ? inherited.$uiView.fqn + "." + name : name, // fully qualified name, describes location in DOM
Expand All @@ -217,6 +218,7 @@ function $ViewDirective( $view, $animate, $uiViewScroll, $interpolate,
trace.traceUiViewEvent("Linking", activeUIView);

function configUpdatedCallback(config?: Ng1ViewConfig) {
if (config && !(config instanceof Ng1ViewConfig)) return;
if (configsEqual(viewConfig, config)) return;
trace.traceUiViewConfigUpdated(activeUIView, config && config.viewDecl && config.viewDecl.$context);

Expand Down
2 changes: 2 additions & 0 deletions src/ng2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
export * from "./core";
import "./justjs";

export * from "./ng2/interface";
export * from "./ng2/providers";
export * from "./ng2/directives";
export * from "./ng2/viewsBuilder";
export * from "./ng2/uiRouterConfig";

7 changes: 4 additions & 3 deletions src/ng2/uiView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {Inject} from "angular2/core";
import {ViewContext, ViewConfig} from "../view/interface";
import {Ng2ViewDeclaration} from "./interface";
import {ng2ComponentInputs} from "./componentUtil";
import {Ng2ViewConfig} from "./viewsBuilder";

/** @hidden */
let id = 0;
Expand Down Expand Up @@ -120,6 +121,7 @@ export class UiView {
let name = this.name || '$default';

this.uiViewData = {
$type: 'ng2',
id: id++,
name: name,
fqn: parentFqn ? parentFqn + "." + name : name,
Expand All @@ -142,9 +144,8 @@ export class UiView {
}

viewConfigUpdated(config: ViewConfig) {
if (!config) {
return this.disposeLast();
}
if (!config) return this.disposeLast();
if (!(config instanceof Ng2ViewConfig)) return;

let {uiViewData, injector, dcl, elementRef} = this;
let viewDecl = <Ng2ViewDeclaration> config.viewDecl;
Expand Down
10 changes: 6 additions & 4 deletions src/path/pathFactory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @module path */ /** for typedoc */

import {extend, find, pick, omit, tail, mergeR, map, values} from "../common/common";
import {extend, find, pick, omit, tail, mergeR, values, unnestR} from "../common/common";
import {prop, propEq, not, curry} from "../common/hof";

import {RawParams} from "../params/interface";
Expand Down Expand Up @@ -40,9 +40,11 @@ export class PathFactory {
}

static applyViewConfigs($view: ViewService, path: Node[]) {
return path.map(node =>
extend(node, { views: values(node.state.views || {}).map(view => $view.createViewConfig(node, view))})
);
return path.map(node => {
let viewDecls = values(node.state.views || {});
let viewConfigs = viewDecls.map(view => $view.createViewConfig(node, view)).reduce(unnestR, []);
return extend(node, {views: viewConfigs})
});
}

/**
Expand Down
9 changes: 8 additions & 1 deletion src/view/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,19 @@ export interface ViewContext {

/** @hidden */
export interface ActiveUIView {
/** type of framework, e.g., "ng1" or "ng2" */
$type: string;
/** An auto-incremented id */
id: number;
/** The ui-view short name */
name: string;
/** The ui-view's fully qualified name */
fqn: string;
/** The ViewConfig that is currently loaded into the ui-view */
config: ViewConfig;
// The context in which the ui-view tag was created.
/** The state context in which the ui-view tag was created. */
creationContext: ViewContext;
/** A callback that should apply a ViewConfig (or clear the ui-view, if config is undefined) */
configUpdated: (config: ViewConfig) => void;
}

Expand Down
14 changes: 10 additions & 4 deletions src/view/view.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @module view */ /** for typedoc */
import {equals, applyPairs, removeFrom, TypedMap} from "../common/common";
import {curry, prop} from "../common/hof";
import {isString} from "../common/predicates";
import {isString, isArray} from "../common/predicates";
import {trace} from "../common/module";
import {Node} from "../path/node";

Expand All @@ -11,7 +11,7 @@ import {_ViewDeclaration} from "../state/interface";
const match = (obj1, ...keys) =>
(obj2) => keys.reduce((memo, key) => memo && obj1[key] === obj2[key], true);

export type ViewConfigFactory = (node: Node, decl: _ViewDeclaration) => ViewConfig;
export type ViewConfigFactory = (node: Node, decl: _ViewDeclaration) => ViewConfig|ViewConfig[];

/**
* The View service
Expand All @@ -32,10 +32,11 @@ export class ViewService {
this._viewConfigFactories[viewType] = factory;
}

createViewConfig(node: Node, decl: _ViewDeclaration): ViewConfig {
createViewConfig(node: Node, decl: _ViewDeclaration): ViewConfig[] {
let cfgFactory = this._viewConfigFactories[decl.$type];
if (!cfgFactory) throw new Error("ViewService: No view config factory registered for type " + decl.$type);
return cfgFactory(node, decl);
let cfgs = cfgFactory(node, decl);
return isArray(cfgs) ? cfgs : [cfgs];
}

/**
Expand Down Expand Up @@ -66,6 +67,8 @@ export class ViewService {
* A ViewConfig has a target ui-view name and a context anchor. The ui-view name can be a simple name, or
* can be a segmented ui-view path, describing a portion of a ui-view fqn.
*
* In order for a ui-view to match ViewConfig, ui-view's $type must match the ViewConfig's $type
*
* If the ViewConfig's target ui-view name is a simple name (no dots), then a ui-view matches if:
* - the ui-view's name matches the ViewConfig's target name
* - the ui-view's context matches the ViewConfig's anchor
Expand Down Expand Up @@ -111,6 +114,9 @@ export class ViewService {
* the tail of the ui-view's fqn "default.bar"
*/
const matches = (uiView: ActiveUIView) => (viewConfig: ViewConfig) => {
// Don't supply an ng1 ui-view with an ng2 ViewConfig, etc
if (uiView.$type !== viewConfig.viewDecl.$type) return false;

// Split names apart from both viewConfig and uiView into segments
let vc = viewConfig.viewDecl;
let vcSegments = vc.$uiViewName.split(".");
Expand Down

0 comments on commit cdf1d19

Please sign in to comment.