@@ -11,6 +11,7 @@ import {trace} from "../common/trace";
11
11
import { Inject } from "angular2/core" ;
12
12
import { ViewContext , ViewConfig } from "../view/interface" ;
13
13
import { Ng2ViewDeclaration } from "./interface" ;
14
+ import { ng2ComponentInputs } from "./componentUtil" ;
14
15
15
16
/** @hidden */
16
17
let id = 0 ;
@@ -23,6 +24,12 @@ const getProviders = (injector) => {
23
24
return providers ;
24
25
} ;
25
26
27
+ // These are provide()d as the string UiView.PARENT_INJECT
28
+ export interface ParentUiViewInject {
29
+ context : ViewContext ;
30
+ fqn : string ;
31
+ }
32
+
26
33
/**
27
34
* A UI-Router viewport directive, which is filled in by a view (component) on a state.
28
35
*
@@ -84,44 +91,39 @@ const getProviders = (injector) => {
84
91
// <div style="padding: 1em; border: 1px solid lightgrey;">
85
92
//
86
93
// <div #content style="color: lightgrey; font-size: smaller;">
87
- // <div>ui-view #{{uiViewData.id}} created by '{{ parentContext.name || "(root)" }}' state</div>
88
- // <div>name: (absolute) '{{uiViewData.fqn}}' (contextual) '{{uiViewData.name}}@{{parentContext.name}}' </div>
89
- // <div>currently filled by: '{{(uiViewData.config && uiViewData.config.viewDecl.$context) || 'empty...'}}'</div>
94
+ // <div>ui-view #{{uiViewData? .id}} created by '{{ parentContext? .name || "(root)" }}' state</div>
95
+ // <div>name: (absolute) '{{uiViewData? .fqn}}' (contextual) '{{uiViewData? .name}}@{{parentContext? .name}}' </div>
96
+ // <div>currently filled by: '{{(uiViewData? .config && uiViewData? .config? .viewDecl? .$context) || 'empty...'}}'</div>
90
97
// </div>
91
98
//
92
99
// </div>`
93
100
} )
94
101
export class UiView {
95
102
@Input ( ) name : string ;
96
- @Input ( ) set 'ui-view' ( val ) { this . name = val ; }
97
-
103
+ @Input ( 'ui-view' ) set _name ( val ) { this . name = val ; }
98
104
componentRef : ComponentRef ;
99
105
deregister : Function ;
100
106
uiViewData : any = { } ;
101
107
102
- static INJECT = {
103
- fqn : "UiView.parentFQN" ,
104
- context : "UiView.parentContext"
105
- } ;
108
+ static PARENT_INJECT = "UiView.PARENT_INJECT" ;
106
109
107
110
constructor (
108
111
public router : UIRouter ,
109
- @Inject ( UiView . INJECT . context ) public parentContext : ViewContext ,
110
- @Inject ( UiView . INJECT . fqn ) public parentFqn : string ,
112
+ @Inject ( UiView . PARENT_INJECT ) public parent : ParentUiViewInject ,
111
113
public dcl : DynamicComponentLoader ,
112
114
public elementRef : ElementRef ,
113
115
public injector : Injector
114
116
) { }
115
117
116
118
ngOnInit ( ) {
117
- let parentFqn = this . parentFqn ;
119
+ let parentFqn = this . parent . fqn ;
118
120
let name = this . name || '$default' ;
119
121
120
122
this . uiViewData = {
121
123
id : id ++ ,
122
124
name : name ,
123
125
fqn : parentFqn ? parentFqn + "." + name : name ,
124
- creationContext : this . parentContext ,
126
+ creationContext : this . parent . context ,
125
127
configUpdated : this . viewConfigUpdated . bind ( this ) ,
126
128
config : undefined
127
129
} ;
@@ -131,10 +133,11 @@ export class UiView {
131
133
132
134
disposeLast ( ) {
133
135
if ( this . componentRef ) this . componentRef . dispose ( ) ;
136
+ this . componentRef = null ;
134
137
}
135
138
136
139
ngOnDestroy ( ) {
137
- this . deregister ( ) ;
140
+ if ( this . deregister ) this . deregister ( ) ;
138
141
this . disposeLast ( ) ;
139
142
}
140
143
@@ -159,17 +162,26 @@ export class UiView {
159
162
let rc = config . node . resolveContext ;
160
163
let resolvables = rc . getResolvables ( ) ;
161
164
let rawProviders = Object . keys ( resolvables ) . map ( key => provide ( key , { useValue : resolvables [ key ] . data } ) ) ;
162
- rawProviders . push ( provide ( UiView . INJECT . context , { useValue : config . viewDecl . $context } ) ) ;
163
- rawProviders . push ( provide ( UiView . INJECT . fqn , { useValue : uiViewData . fqn } ) ) ;
165
+ rawProviders . push ( provide ( UiView . PARENT_INJECT , { useValue : { context : config . viewDecl . $context , fqn : uiViewData . fqn } } ) ) ;
164
166
let providers = Injector . resolve ( rawProviders ) ;
165
167
166
- let exclusions = [ UiView . INJECT . context , UiView . INJECT . fqn ] ;
168
+ let exclusions = [ UiView . PARENT_INJECT ] ;
167
169
providers = getProviders ( injector ) . filter ( x => exclusions . indexOf ( x . key . displayName ) === - 1 ) . concat ( providers ) ;
168
170
169
- // The 'controller' should be a Component class
170
- // TODO: pull from 'component' declaration, do not require template.
171
171
let component = < Type > viewDecl . component ;
172
- dcl . loadIntoLocation ( component , elementRef , "content" , providers ) . then ( ref => this . componentRef = ref ) ;
172
+ dcl . loadIntoLocation ( component , elementRef , "content" , providers ) . then ( ref => {
173
+ this . componentRef = ref ;
174
+
175
+ // TODO: wire uiCanExit and uiOnParamsChanged callbacks
176
+
177
+ // Set resolve data to matching @Input ("prop")
178
+ let inputs = ng2ComponentInputs ( component ) ;
179
+ let bindings = viewDecl [ 'bindings' ] || { } ;
180
+
181
+ inputs . map ( tuple => ( { prop : tuple . prop , resolve : bindings [ tuple . prop ] || tuple . resolve } ) )
182
+ . filter ( tuple => resolvables [ tuple . resolve ] !== undefined )
183
+ . forEach ( tuple => { ref . instance [ tuple . prop ] = resolvables [ tuple . resolve ] . data } ) ;
184
+ } ) ;
173
185
}
174
186
}
175
187
0 commit comments