Skip to content

Commit cdf1d19

Browse files
refactor(viewService): only match ViewConfigs with ui-views of same $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
1 parent 9111727 commit cdf1d19

File tree

6 files changed

+32
-12
lines changed

6 files changed

+32
-12
lines changed

src/ng1/viewDirective.ts

+2
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ function $ViewDirective( $view, $animate, $uiViewScroll, $interpolate,
204204
name = $interpolate(attrs.uiView || attrs.name || '')(scope) || '$default';
205205

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

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

src/ng2.ts

+2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
export * from "./core";
88
import "./justjs";
99

10+
export * from "./ng2/interface";
1011
export * from "./ng2/providers";
1112
export * from "./ng2/directives";
13+
export * from "./ng2/viewsBuilder";
1214
export * from "./ng2/uiRouterConfig";
1315

src/ng2/uiView.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {Inject} from "angular2/core";
1212
import {ViewContext, ViewConfig} from "../view/interface";
1313
import {Ng2ViewDeclaration} from "./interface";
1414
import {ng2ComponentInputs} from "./componentUtil";
15+
import {Ng2ViewConfig} from "./viewsBuilder";
1516

1617
/** @hidden */
1718
let id = 0;
@@ -120,6 +121,7 @@ export class UiView {
120121
let name = this.name || '$default';
121122

122123
this.uiViewData = {
124+
$type: 'ng2',
123125
id: id++,
124126
name: name,
125127
fqn: parentFqn ? parentFqn + "." + name : name,
@@ -142,9 +144,8 @@ export class UiView {
142144
}
143145

144146
viewConfigUpdated(config: ViewConfig) {
145-
if (!config) {
146-
return this.disposeLast();
147-
}
147+
if (!config) return this.disposeLast();
148+
if (!(config instanceof Ng2ViewConfig)) return;
148149

149150
let {uiViewData, injector, dcl, elementRef} = this;
150151
let viewDecl = <Ng2ViewDeclaration> config.viewDecl;

src/path/pathFactory.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/** @module path */ /** for typedoc */
22

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

66
import {RawParams} from "../params/interface";
@@ -40,9 +40,11 @@ export class PathFactory {
4040
}
4141

4242
static applyViewConfigs($view: ViewService, path: Node[]) {
43-
return path.map(node =>
44-
extend(node, { views: values(node.state.views || {}).map(view => $view.createViewConfig(node, view))})
45-
);
43+
return path.map(node => {
44+
let viewDecls = values(node.state.views || {});
45+
let viewConfigs = viewDecls.map(view => $view.createViewConfig(node, view)).reduce(unnestR, []);
46+
return extend(node, {views: viewConfigs})
47+
});
4648
}
4749

4850
/**

src/view/interface.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,19 @@ export interface ViewContext {
1212

1313
/** @hidden */
1414
export interface ActiveUIView {
15+
/** type of framework, e.g., "ng1" or "ng2" */
16+
$type: string;
17+
/** An auto-incremented id */
1518
id: number;
19+
/** The ui-view short name */
1620
name: string;
21+
/** The ui-view's fully qualified name */
1722
fqn: string;
23+
/** The ViewConfig that is currently loaded into the ui-view */
1824
config: ViewConfig;
19-
// The context in which the ui-view tag was created.
25+
/** The state context in which the ui-view tag was created. */
2026
creationContext: ViewContext;
27+
/** A callback that should apply a ViewConfig (or clear the ui-view, if config is undefined) */
2128
configUpdated: (config: ViewConfig) => void;
2229
}
2330

src/view/view.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/** @module view */ /** for typedoc */
22
import {equals, applyPairs, removeFrom, TypedMap} from "../common/common";
33
import {curry, prop} from "../common/hof";
4-
import {isString} from "../common/predicates";
4+
import {isString, isArray} from "../common/predicates";
55
import {trace} from "../common/module";
66
import {Node} from "../path/node";
77

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

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

1616
/**
1717
* The View service
@@ -32,10 +32,11 @@ export class ViewService {
3232
this._viewConfigFactories[viewType] = factory;
3333
}
3434

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

4142
/**
@@ -66,6 +67,8 @@ export class ViewService {
6667
* A ViewConfig has a target ui-view name and a context anchor. The ui-view name can be a simple name, or
6768
* can be a segmented ui-view path, describing a portion of a ui-view fqn.
6869
*
70+
* In order for a ui-view to match ViewConfig, ui-view's $type must match the ViewConfig's $type
71+
*
6972
* If the ViewConfig's target ui-view name is a simple name (no dots), then a ui-view matches if:
7073
* - the ui-view's name matches the ViewConfig's target name
7174
* - the ui-view's context matches the ViewConfig's anchor
@@ -111,6 +114,9 @@ export class ViewService {
111114
* the tail of the ui-view's fqn "default.bar"
112115
*/
113116
const matches = (uiView: ActiveUIView) => (viewConfig: ViewConfig) => {
117+
// Don't supply an ng1 ui-view with an ng2 ViewConfig, etc
118+
if (uiView.$type !== viewConfig.viewDecl.$type) return false;
119+
114120
// Split names apart from both viewConfig and uiView into segments
115121
let vc = viewConfig.viewDecl;
116122
let vcSegments = vc.$uiViewName.split(".");

0 commit comments

Comments
 (0)