Skip to content

Commit 827b070

Browse files
committed
Add query-list injection demo.
1 parent 777cd17 commit 827b070

3 files changed

Lines changed: 285 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+
* [Constructor vs. Property QueryList Injection In Angular 2 Beta 8](http://bennadel.github.io/JavaScript-Demos/demos/query-list-injection-angular2/)
1314
* [I Have A Fundamental Misunderstanding Of Change Detection In Angular 2 Beta 8](http://bennadel.github.io/JavaScript-Demos/demos/fundamental-misunderstanding-change-detection-angular2/)
1415
* [Logging Error Streams To The Server In Angular 2 Beta 6](http://bennadel.github.io/JavaScript-Demos/demos/error-stream-logging-angular2/)
1516
* [EventEmitter Is An RxJS Observable Stream In Angular 2 Beta 6](http://bennadel.github.io/JavaScript-Demos/demos/event-emitter-stream-angular2/)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
item-a,
3+
item-b {
4+
border: 1px solid #CCCCCC ;
5+
border-radius: 3px 3px 3px 3px ;
6+
display: inline-block ;
7+
margin: 0px 10px 16px 0px ;
8+
padding: 8px 15px 8px 15px ;
9+
}
Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
6+
<title>
7+
Constructor vs. Property QueryList Injection In Angular 2 Beta 8
8+
</title>
9+
10+
<link rel="stylesheet" type="text/css" href="./demo.css"></link>
11+
</head>
12+
<body>
13+
14+
<h1>
15+
Constructor vs. Property QueryList Injection In Angular 2 Beta 8
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/8/es6-shim.min.js"></script>
24+
<script type="text/javascript" src="../../vendor/angularjs-2-beta/8/Rx.umd.min.js"></script>
25+
<script type="text/javascript" src="../../vendor/angularjs-2-beta/8/angular2-polyfills.min.js"></script>
26+
<script type="text/javascript" src="../../vendor/angularjs-2-beta/8/angular2-all.umd.js"></script>
27+
<!-- AlmondJS - minimal implementation of RequireJS. -->
28+
<script type="text/javascript" src="../../vendor/angularjs-2-beta/8/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+
var App = require( "App" );
40+
41+
ng.platform.browser.bootstrap( App );
42+
43+
}
44+
);
45+
46+
47+
// --------------------------------------------------------------------------- //
48+
// --------------------------------------------------------------------------- //
49+
50+
51+
// I provide the root App component.
52+
define(
53+
"App",
54+
function registerApp() {
55+
56+
var ItemA = require( "ItemA" );
57+
var ItemB = require( "ItemB" );
58+
59+
// Configure the App component definition.
60+
ng.core
61+
.Component({
62+
selector: "my-app",
63+
directives: [ ItemA, ItemB ],
64+
65+
// Here, we are asking Angular to inject a query list for the
66+
// collection of ItemA components rendered within our component
67+
// view. This will inject `itemAList` as a public property on
68+
// the App component instance.
69+
// --
70+
// CAUTION: View queries are set before the ngAfterViewInit()
71+
// life-cycle method is called, but after the ngOnInit() life-
72+
// cycle method is called. As such, the `itemAList` property will
73+
// not exist until the View is initialized.
74+
queries: {
75+
itemAList: new ng.core.ViewChildren( ItemA )
76+
},
77+
78+
// Notice that our view has two different sets of components -
79+
// ItemA and ItemB instances. Each of these will be monitored
80+
// using a different live query.
81+
template:
82+
`
83+
<item-a></item-a>
84+
<item-a></item-a>
85+
<br />
86+
<item-b></item-b>
87+
<item-b></item-b>
88+
<item-b></item-b>
89+
90+
<div *ngIf="showMore">
91+
<item-a></item-a>
92+
<item-b></item-b>
93+
</div>
94+
`
95+
})
96+
.Class({
97+
constructor: AppController,
98+
99+
// Define life-cycle methods on the prototype so that they are
100+
// picked up at runtime.
101+
ngOnInit: function noop() {},
102+
ngAfterViewInit: function noop() {}
103+
})
104+
;
105+
106+
// Here, we're asking Angular to inject a live query of the ItemB view
107+
// children as a constructor argument for the component instance. Just
108+
// like the live query defined in the component meta-data, this one will
109+
// not contain items until the view has been initialized. However, unlike
110+
// the other live query, we can at least reference this variable before
111+
// the view has been initialized (where we can subscribe to the changes).
112+
AppController.parameters = [
113+
[
114+
new ng.core.Inject( ng.core.ViewChildren ),
115+
new ng.core.ViewChildren( ItemB )
116+
]
117+
];
118+
119+
return( AppController );
120+
121+
122+
// I control the App component.
123+
function AppController( itemBList ) {
124+
125+
var vm = this;
126+
127+
// I determine if we are showing the extra components.
128+
vm.showMore = false;
129+
130+
// The ViewChildren construct is a live query of the components in
131+
// the view. So, in order to see how this live query changes over
132+
// time, we're going to reveal more components after a short delay.
133+
setTimeout(
134+
function revealMore() {
135+
136+
console.info( "- - - - Reveal More Components - - - -" );
137+
vm.showMore = true;
138+
139+
},
140+
( 5 * 1000 )
141+
);
142+
143+
// While the itemBList was provided via constructor injection, the
144+
// view still has not yet been initialized. As such, this list will
145+
// be empty. But, since we have a reference to it, we can subscribe
146+
// to changes (that will be triggered after the view is initialized).
147+
itemBList.changes.subscribe(
148+
function handleValue( queryList ) {
149+
150+
console.warn( "itemBList Change Detection (constructor)" );
151+
console.log( "itemBList:", itemBList.length );
152+
153+
}
154+
);
155+
156+
// Expose the public methods.
157+
vm.ngAfterViewInit = ngAfterViewInit;
158+
vm.ngOnInit = ngOnInit;
159+
160+
161+
// ---
162+
// PUBLIC METHODS.
163+
// ---
164+
165+
166+
// I get called once after the component's view has been initialized.
167+
function ngAfterViewInit() {
168+
169+
// At this point, after the view has been initialized, both of the
170+
// query list values are available - both itemBList, which was
171+
// injected via the constructor, and itemAList, which was just
172+
// injected as a property.
173+
console.warn( "ngAfterViewInit()" );
174+
console.log( "itemAList:", vm.itemAList.length );
175+
console.log( "itemBList:", itemBList.length );
176+
177+
// Now that we finally have a reference to the itemAList, let's
178+
// subscribe to the changes of the list (which updates the current
179+
// instance but also provides a reference to the query list).
180+
vm.itemAList.changes.subscribe(
181+
function handleValue( queryList ) {
182+
183+
console.warn( "itemAList Change Detection (ngAfterViewInit)" );
184+
console.log( "itemAList:", vm.itemAList.length );
185+
186+
}
187+
);
188+
189+
// We've already subscribed to the changes on this list; but,
190+
// let's do it again so we can see if it would pick up the initial
191+
// length of the list.
192+
itemBList.changes.subscribe(
193+
function handleValue( queryList ) {
194+
195+
console.warn( "itemBList Change Detection (ngAfterViewInit)" );
196+
console.log( "itemBList:", itemBList.length );
197+
198+
}
199+
);
200+
201+
}
202+
203+
204+
// I get called once after the component has been instantiated and
205+
// the inputs have been bound (and observed once).
206+
function ngOnInit() {
207+
208+
// While the itemBList was injected in the constructor, the
209+
// itemAList, which was part of the component meta-data, has not
210+
// been injected.
211+
console.warn( "ngOnInit()" );
212+
console.log( "itemAList:", ( vm.itemAList && vm.itemAList.length ) );
213+
console.log( "itemBList:", itemBList.length );
214+
215+
}
216+
217+
}
218+
219+
}
220+
);
221+
222+
223+
// --------------------------------------------------------------------------- //
224+
// --------------------------------------------------------------------------- //
225+
226+
227+
// I provide a super simple Component for no other purpose than to have a
228+
// component that can be rendered in the App component.
229+
define(
230+
"ItemA",
231+
function registerItemA() {
232+
233+
// Configure the Item component definition.
234+
return ng.core
235+
.Component({
236+
selector: "item-a",
237+
template: "This is an ItemA!"
238+
})
239+
.Class({
240+
constructor: function ItemControllerA() { /* Nothing to do. */ }
241+
})
242+
;
243+
244+
}
245+
);
246+
247+
248+
// --------------------------------------------------------------------------- //
249+
// --------------------------------------------------------------------------- //
250+
251+
252+
// I provide a super simple Component for no other purpose than to have a
253+
// component that can be rendered in the App component.
254+
define(
255+
"ItemB",
256+
function registerItemB() {
257+
258+
// Configure the Item component definition.
259+
return ng.core
260+
.Component({
261+
selector: "item-b",
262+
template: "This is an ItemB!"
263+
})
264+
.Class({
265+
constructor: function ItemControllerB() { /* Nothing to do. */ }
266+
})
267+
;
268+
269+
}
270+
);
271+
272+
</script>
273+
274+
</body>
275+
</html>

0 commit comments

Comments
 (0)