1+ <!doctype html>
2+ < html >
3+ < head >
4+ < meta charset ="utf-8 " />
5+
6+ < title >
7+ Injecting HTML With The BrowserDomAdapter In AngularJS 2 Beta 9
8+ </ title >
9+
10+ < link rel ="stylesheet " type ="text/css " href ="./demo.css "> </ link >
11+ </ head >
12+ < body >
13+
14+ < h1 >
15+ Injecting HTML With The BrowserDomAdapter In AngularJS 2 Beta 9
16+ </ h1 >
17+
18+ < my-app >
19+ Loading...
20+ </ my-app >
21+
22+ <!-- Load demo scripts. -->
23+ < script type ="text/javascript " src ="../../vendor/angularjs-2-beta/9/es6-shim.min.js "> </ script >
24+ < script type ="text/javascript " src ="../../vendor/angularjs-2-beta/9/Rx.umd.min.js "> </ script >
25+ < script type ="text/javascript " src ="../../vendor/angularjs-2-beta/9/angular2-polyfills.min.js "> </ script >
26+ < script type ="text/javascript " src ="../../vendor/angularjs-2-beta/9/angular2-all.umd.js "> </ script >
27+ <!-- AlmondJS - minimal implementation of RequireJS. -->
28+ < script type ="text/javascript " src ="../../vendor/angularjs-2-beta/9/almond.js "> </ script >
29+ < script type ="text/javascript ">
30+
31+ // Defer bootstrapping until all of the components have been declared.
32+ // --
33+ // NOTE: Not all components have to be required here since they will be
34+ // implicitly required by other components.
35+ requirejs (
36+ [ /* Using require() for better readability. */ ] ,
37+ function run ( ) {
38+
39+ ng . platform . browser . bootstrap ( require ( "App" ) ) ;
40+
41+ }
42+ ) ;
43+
44+
45+ // --------------------------------------------------------------------------- //
46+ // --------------------------------------------------------------------------- //
47+
48+
49+ // I control the root of the application.
50+ define (
51+ "App" ,
52+ function registerApp ( ) {
53+
54+ // Define the App component metadata.
55+ ng . core
56+ . Component ( {
57+ selector : "my-app" ,
58+ directives : [
59+ require ( "SelectList" ) ,
60+ require ( "SelectItem" )
61+ ] ,
62+ template :
63+ `
64+ <select-list>
65+ <select-item>As if!</select-item>
66+ <select-item>Totes magotes!</select-item>
67+ <select-item>So inappropes!</select-item>
68+ <select-item>Much wow!</select-item>
69+ </select-list>
70+ `
71+ } )
72+ . Class ( {
73+ constructor : AppController
74+ } )
75+ ;
76+
77+ return ( AppController ) ;
78+
79+
80+ // I control the App component.
81+ function AppController ( ) {
82+
83+ // ... nothing to do there.
84+
85+ }
86+
87+ }
88+ ) ;
89+
90+
91+ // --------------------------------------------------------------------------- //
92+ // --------------------------------------------------------------------------- //
93+
94+
95+ // I provide the SelectList component.
96+ define (
97+ "SelectList" ,
98+ function registerSelectList ( ) {
99+
100+ // Define the SelectList component metadata.
101+ ng . core
102+ . Component ( {
103+ selector : "select-list" ,
104+
105+ // CAUTION: We are providing the BrowserDomAdapter to the
106+ // component. At this point, we are making a very strong
107+ // assertion about which environments this component can run in
108+ // (which I think - but am not sure - means that this component
109+ // can never be rendered on the server; or at least not without
110+ // first mocking out the BrowserDomAdapter to work without a
111+ // native HTML DOM implementation).
112+ providers : [ ng . platform . browser . BrowserDomAdapter ] ,
113+
114+ // When an item is selected, we are going represent it in the
115+ // component by injecting its HTML into the snapshot. To make
116+ // this easier, let's get a live query to the snapshot element
117+ // reference.
118+ queries : {
119+ "snapshotElementRef" : new ng . core . ViewChild ( "snapshot" )
120+ } ,
121+ template :
122+ `
123+ <div #snapshot class="snapshot">
124+ <em class="default">Nothing selected</em>
125+ </div>
126+
127+ <ng-content></ng-content>
128+ `
129+ } )
130+ . Class ( {
131+ constructor : SelectListController
132+ } )
133+ ;
134+
135+ SelectListController . parameters = [
136+ new ng . core . Inject ( ng . platform . browser . BrowserDomAdapter )
137+ ] ;
138+
139+ return ( SelectListController ) ;
140+
141+
142+ // I control the SelectList component.
143+ function SelectListController ( domAdapter ) {
144+
145+ var vm = this ;
146+
147+ // Expose the public methods.
148+ vm . selectItem = selectItem ;
149+
150+
151+ // ---
152+ // PUBLIC METHODS.
153+ // ---
154+
155+
156+ // I use the given item as the selected item.
157+ function selectItem ( item ) {
158+
159+ // When an item in the list wants to be the selected item, we
160+ // are going to represent it in the component by projecting
161+ // its HTML content into the snapshot container. In order to do
162+ // that, we need to get elementRef of the item.
163+ var itemElementRef = item . getElementRef ( ) ;
164+
165+ // At this point, we have to reach down past the generic DOM
166+ // abstraction and make many assumptions that we are working with
167+ // the BrowserDomAdapter, which makes it possible to actually grab
168+ // the innerHTML content of one element and inject it into another
169+ // element. Not only does this require the BrowserDomAdapter, it
170+ // also requires us to reach into the ElementRef instances and
171+ // consume the underlying nativeElement.
172+ // --
173+ // NOTE: I am really not sure that this is good. I hate the fact
174+ // that we have to start assuming things about the DOM. If anyone
175+ // knows of a generic way to do this, please share!
176+ domAdapter . setInnerHTML (
177+ vm . snapshotElementRef . nativeElement ,
178+ domAdapter . getInnerHTML ( itemElementRef . nativeElement )
179+ ) ;
180+
181+ // ASIDE: At this point, you may be wondering, if we're already
182+ // making assumptions about the DOM, why not just use the native
183+ // .innerHTML property and skip the BrowserDomAdpater altogether?
184+ // Well, if we go through the BrowserDomAdpater, we still have
185+ // option to *mock out* the BrowserDomAdapter. If we start
186+ // reaching into the native properties, we lose the ability to
187+ // mock out or override the adapter in other rendering contexts.
188+
189+ }
190+
191+ }
192+
193+ }
194+ ) ;
195+
196+
197+ // --------------------------------------------------------------------------- //
198+ // --------------------------------------------------------------------------- //
199+
200+
201+ // I provide the SelectItem component.
202+ define (
203+ "SelectItem" ,
204+ function registerSelectItem ( ) {
205+
206+ // Define the SelectItem component metadata.
207+ ng . core
208+ . Component ( {
209+ selector : "select-item" ,
210+ host : {
211+ "(click)" : "selectItem()"
212+ } ,
213+ template :
214+ `
215+ <ng-content></ng-content>
216+ `
217+ } )
218+ . Class ( {
219+ constructor : SelectItemController
220+ } )
221+ ;
222+
223+ // Here, were injecting the components host element reference and the
224+ // SelectList component. The SelectList component will be provided by
225+ // the hierarchy of parent components.
226+ SelectItemController . parameters = [
227+ new ng . core . Inject ( ng . core . ElementRef ) ,
228+ new ng . core . Inject ( require ( "SelectList" ) )
229+ ] ;
230+
231+ return ( SelectItemController ) ;
232+
233+
234+ // I control the SelectItem component. The item really only has one
235+ // behavior and that is to tell the parent list when the item has been
236+ // selected (ie, clicked) by the user.
237+ function SelectItemController ( elementRef , selectList ) {
238+
239+ var vm = this ;
240+
241+ // Expose the public methods.
242+ vm . getElementRef = getElementRef ;
243+ vm . selectItem = selectItem ;
244+
245+
246+ // ---
247+ // PUBLIC METHODS.
248+ // ---
249+
250+
251+ // I return the element wrapper for this component instance.
252+ function getElementRef ( ) {
253+
254+ // NOTE: At this point, we still make no assumptions about the
255+ // platform. The ElementRef is the Angular 2 wrapper around
256+ // whatever the platform uses to represent its object model.
257+ return ( elementRef ) ;
258+
259+ }
260+
261+
262+ // I tell the parent list to use this item as the selected item.
263+ function selectItem ( ) {
264+
265+ selectList . selectItem ( this ) ;
266+
267+ }
268+
269+ }
270+
271+ }
272+ ) ;
273+
274+ </ script >
275+
276+ </ body >
277+ </ html >
0 commit comments