Skip to content

Commit 893fba0

Browse files
committed
InnerHTML example with Angular 2.
1 parent 72bef36 commit 893fba0

3 files changed

Lines changed: 313 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ with.
1010

1111
## My JavaScript Demos - I Love JavaScript!
1212

13+
* [Injecting HTML With The BrowserDomAdapter In AngularJS 2 Beta 9](http://bennadel.github.io/JavaScript-Demos/demos/title-platform-agnostic-angular2/)
1314
* [Setting The Document Title Using Platform-Agnostic Methods In Angular 2 Beta 9](http://bennadel.github.io/JavaScript-Demos/demos/title-platform-agnostic-angular2/)
1415
* [Setting The Window / Document Title In Angular 2 Beta 9](http://bennadel.github.io/JavaScript-Demos/demos/title-angular2/)
1516
* [Converting A Subject To An Observable Using RxJS In Angular 2 Beta 9](http://bennadel.github.io/JavaScript-Demos/demos/subject-to-observable-angular2/)

demos/copy-html-angular2/demo.css

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
2+
select-list {
3+
border: 2px solid #CCCCCC ;
4+
border-radius: 4px 4px 4px 4px ;
5+
box-sizing: border-box ;
6+
display: block ;
7+
padding: 20px 20px 20px 20px ;
8+
width: 300px ;
9+
}
10+
11+
select-list div.snapshot {
12+
border: 1px solid #333333 ;
13+
border-radius: 4px 4px 4px 4px ;
14+
margin-bottom: 20px ;
15+
padding: 10px 10px 10px 10px ;
16+
}
17+
18+
select-list div.snapshot em.default {
19+
color: #999999 ;
20+
}
21+
22+
select-item {
23+
border: 1px solid #CCCCCC ;
24+
border-radius: 4px 4px 4px 4px ;
25+
box-sizing: border-box ;
26+
cursor: pointer ;
27+
display: block ;
28+
margin-top: 10px ;
29+
padding: 10px 10px 10px 10px ;
30+
}
31+
32+
select-item:hover {
33+
background-color: #FAFAFA ;
34+
border-color: #AAAAAA ;
35+
}

demos/copy-html-angular2/index.htm

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
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

Comments
 (0)