@@ -31,7 +31,7 @@ you will have access to a new `ember` command in your terminal.
31
31
You can use the ` ember new ` command to create a new application.
32
32
33
33
``` bash
34
- ember new ember-quickstart --lang en
34
+ ember new ember-quickstart --lang en --strict
35
35
```
36
36
37
37
This one command will create a new directory called ` ember-quickstart ` and set up a new Ember application inside of it.
@@ -87,8 +87,6 @@ Congratulations! You just created and booted your first Ember app.
87
87
88
88
## Write some HTML in a template
89
89
90
- <feature-flag-on-template-tag >
91
-
92
90
We will start by editing the ` application ` template.
93
91
This template is always on screen while the user has your application loaded.
94
92
In your editor, open ` app/templates/application.gjs ` and change it to the following:
@@ -99,21 +97,6 @@ In your editor, open `app/templates/application.gjs` and change it to the follow
99
97
{{outlet}}
100
98
</template>
101
99
```
102
- </feature-flag-on-template-tag >
103
-
104
- <feature-flag-off-template-tag >
105
-
106
- We will start by editing the ` application ` template.
107
- This template is always on screen while the user has your application loaded.
108
- In your editor, open ` app/templates/application.hbs ` and change it to the following:
109
-
110
- ``` handlebars {data-filename=app/templates/application.hbs}
111
- <h1>PeopleTracker</h1>
112
-
113
- {{outlet}}
114
- ```
115
-
116
- </feature-flag-off-template-tag >
117
100
118
101
Ember detects the changed file and automatically reloads the page for you in the background.
119
102
You should see that the welcome page has been replaced by "PeopleTracker".
@@ -135,21 +118,7 @@ ember generate route scientists
135
118
136
119
You'll see output like this:
137
120
138
- <feature-flag-off-template-tag >
139
- ``` text
140
- installing route
141
- create app/routes/scientists.js
142
- create app/templates/scientists.hbs
143
- updating router
144
- add route scientists
145
- installing route-test
146
- create tests/unit/routes/scientists-test.js
147
- ```
148
- </feature-flag-off-template-tag >
149
- <feature-flag-on-template-tag >
150
121
``` bash
151
- # 🚧 Under construction 🚧
152
- # `ember generate route` has not been updated to produce GJS files yet.
153
122
installing route
154
123
create app/routes/scientists.js
155
124
create app/templates/scientists.gjs
@@ -158,7 +127,6 @@ updating router
158
127
installing route-test
159
128
create tests/unit/routes/scientists-test.js
160
129
```
161
- </feature-flag-on-template-tag >
162
130
163
131
That is Ember telling you that it has created:
164
132
@@ -167,20 +135,7 @@ That is Ember telling you that it has created:
167
135
3 . An entry in the application's router (located in ` app/router.js ` ).
168
136
4 . A unit test for this route.
169
137
170
- <feature-flag-off-template-tag >
171
- Open the newly-created template in ` app/templates/scientists.hbs ` and add the following HTML:
172
-
173
- ``` handlebars {data-filename=app/templates/scientists.hbs}
174
- {{page-title "Scientists"}}
175
- <h2>List of Scientists</h2>
176
- ```
177
-
178
- In your browser, open [ ` http://localhost:4200/scientists ` ] ( http://localhost:4200/scientists ) .
179
- You should see the ` <h2> ` we put in the ` scientists.hbs ` template right below the ` <h1> ` from our ` application.hbs ` template.
180
-
181
- </feature-flag-off-template-tag >
182
- <feature-flag-on-template-tag >
183
- Open the newly-created template in ` app/templates/scientists.gjs ` and add the following HTML:
138
+ Open the newly-created template in ` app/templates/scientists.gjs ` and add the following code:
184
139
185
140
``` gjs {data-filename=app/templates/scientists.gjs}
186
141
import { pageTitle } from 'ember-page-title';
@@ -194,8 +149,6 @@ import { pageTitle } from 'ember-page-title';
194
149
In your browser, open [ ` http://localhost:4200/scientists ` ] ( http://localhost:4200/scientists ) .
195
150
You should see the ` <h2> ` we put in the ` scientists.gjs ` template right below the ` <h1> ` from our ` application.gjs ` template.
196
151
197
- </feature-flag-on-template-tag >
198
-
199
152
Since the scientist route is nested under the application route, Ember will render its content inside the application route template's ` {{outlet}} ` directive.
200
153
201
154
Now that we've got the ` scientists ` template rendering,
@@ -225,19 +178,6 @@ the `model()` method supports any library that uses [JavaScript Promises](https:
225
178
Now let's tell Ember how to turn that array of strings into HTML.
226
179
Open the ` scientists ` template and add the following code to loop through the array and print it:
227
180
228
- <feature-flag-off-template-tag >
229
- ``` handlebars {data-filename="app/templates/scientists.hbs"}
230
- <h2>List of Scientists</h2>
231
-
232
- <ul>
233
- {{#each @model as |scientist|}}
234
- <li>{{scientist}}</li>
235
- {{/each}}
236
- </ul>
237
- ```
238
- </feature-flag-off-template-tag >
239
-
240
- <feature-flag-on-template-tag >
241
181
``` gjs {data-filename="app/templates/scientists.gjs"}
242
182
import { pageTitle } from 'ember-page-title';
243
183
@@ -251,7 +191,6 @@ import { pageTitle } from 'ember-page-title';
251
191
</ul>
252
192
</template>
253
193
```
254
- </feature-flag-on-template-tag >
255
194
256
195
Here, we use the ` each ` _ helper_ to loop over each item in the array we
257
196
provided from the ` model() ` hook. Ember will render the _ block_ contained
@@ -275,30 +214,24 @@ As usual, there's a generator that makes this easy for us.
275
214
Make a new component by typing:
276
215
277
216
``` bash
278
- < feature-flag-on-template-tag>
279
- # 🚧 Under construction 🚧
280
- # `ember generate component` has not been updated to produce GJS files yet.
281
- < /feature-flag-on-template-tag>
282
217
ember generate component people-list
283
218
```
284
219
285
- <feature-flag-off-template-tag >
286
- Copy and paste the ` scientists ` template into the ` PeopleList ` component's template and edit it to look as follows:
287
-
288
- ``` handlebars {data-filename=app/components/people-list.hbs}
289
- <h2>{{@title}}</h2>
220
+ You'll see output like this:
290
221
291
- <ul>
292
- {{#each @people as |person|}}
293
- <li>{{person}}</li>
294
- {{/each}}
295
- </ul>
222
+ ``` bash
223
+ installing component
224
+ create app/components/people-list.gjs
225
+ installing component-test
226
+ create tests/integration/components/people-list-test.gjs
296
227
```
297
228
298
- </feature-flag-off-template-tag >
229
+ That is Ember telling you that it has created:
230
+
231
+ 1 . A ` people-list ` component in the ` components ` folder
232
+ 2 . A ` people-list-test ` integration test file that you can use to test your component
299
233
300
- <feature-flag-on-template-tag >
301
- Copy and paste this part of the ` scientists ` template into the ` PeopleList ` component and edit it to look as follows:
234
+ Copy and paste this part of the ` scientists ` template into the newly created ` PeopleList ` component and edit it to look as follows:
302
235
303
236
``` gjs {data-filename=app/components/people-list.gjs}
304
237
<template>
@@ -312,8 +245,6 @@ Copy and paste this part of the `scientists` template into the `PeopleList` comp
312
245
</template>
313
246
```
314
247
315
- </feature-flag-on-template-tag >
316
-
317
248
Note that we've changed the title from a hard-coded string ("List of Scientists")
318
249
to ` {{@title}} ` . The ` @ ` indicates that ` @title ` is an argument that will be
319
250
passed into the component, which makes it easier to reuse the same component in
@@ -322,24 +253,6 @@ other parts of the app we are building.
322
253
We've also renamed ` scientist ` to the more-generic ` person ` ,
323
254
decreasing the coupling of our component to where it's used.
324
255
325
- <feature-flag-off-template-tag >
326
- Our component is called ` PeopleList ` , based on its name on the file system. Please note that the letters P and L are capitalized.
327
-
328
- <div class =" cta " >
329
- <div class =" cta-note " >
330
- <div class="cta-note-body">
331
- <div class="cta-note-heading">Zoey says...</div>
332
- <div class="cta-note-message">
333
- A component's name is derived from its file name.
334
- We capitalize the first letter and every letter after <code>-</code>, then remove the hyphens.
335
- This is known as pascal case.
336
- </div>
337
- </div>
338
- <img src="/images/mascots/zoey.png" role="presentation" alt="">
339
- </div >
340
- </div >
341
- </feature-flag-off-template-tag >
342
-
343
256
Save this template and switch back to the ` scientists ` template.
344
257
345
258
We're going to tell our component:
@@ -354,23 +267,6 @@ In the rest of the code examples in this tutorial, whenever we add or remove cod
354
267
355
268
Let's replace all our old code with our new componentized version:
356
269
357
- <feature-flag-off-template-tag >
358
- ``` handlebars {data-filename="app/templates/scientists.hbs" data-diff="-1,-2,-3,-4,-5,-6,-7,+8,+9,+10,+11"}
359
- <h2>List of Scientists</h2>
360
-
361
- <ul>
362
- {{#each @model as |scientist|}}
363
- <li>{{scientist}}</li>
364
- {{/each}}
365
- </ul>
366
- <PeopleList
367
- @title="List of Scientists"
368
- @people={{@model}}
369
- />
370
- ```
371
- </feature-flag-off-template-tag >
372
-
373
- <feature-flag-on-template-tag >
374
270
``` gjs {data-filename="app/templates/scientists.gjs" data-diff="+2,-6,-7,-8,-9,-10,-11,+12,+13,+14,+15"}
375
271
import { pageTitle } from 'ember-page-title';
376
272
import PeopleList from '../components/people-list';
@@ -389,7 +285,6 @@ import PeopleList from '../components/people-list';
389
285
/>
390
286
</template>
391
287
```
392
- </feature-flag-on-template-tag >
393
288
394
289
Go back to your browser and you should see that the UI looks identical.
395
290
The only difference is that now we've componentized our list into a version that's more reusable and more maintainable.
@@ -407,20 +302,6 @@ user actions like clicks or hovers. Ember makes this easy to do.
407
302
408
303
First, we can modify the ` PeopleList ` component to include a button:
409
304
410
- <feature-flag-off-template-tag >
411
- ``` handlebars {data-filename="app/components/people-list.hbs"}
412
- <h2>{{@title}}</h2>
413
-
414
- <ul>
415
- {{#each @people as |person|}}
416
- <li>
417
- <button type="button">{{person}}</button>
418
- </li>
419
- {{/each}}
420
- </ul>
421
- ```
422
- </feature-flag-off-template-tag >
423
- <feature-flag-on-template-tag >
424
305
``` gjs {data-filename="app/components/people-list.gjs"}
425
306
<template>
426
307
<h2>{{@title}}</h2>
@@ -434,8 +315,6 @@ First, we can modify the `PeopleList` component to include a button:
434
315
</ul>
435
316
</template>
436
317
```
437
- </feature-flag-on-template-tag >
438
-
439
318
440
319
Now that we have a button, we need to wire it up to do _ something_ when a user
441
320
clicks on it. For simplicity, let's say we want to show an ` alert ` dialog with
@@ -446,79 +325,6 @@ inputs as arguments and renders them using a template. To introduce _behavior_
446
325
to our component – handling the button click in this case, we will need to
447
326
attach some JavaScript to the component.
448
327
449
- <feature-flag-off-template-tag >
450
- In addition to the template, a component can also have a JavaScript file for
451
- this exact purpose. Go ahead and create a ` .js ` file with the same name and in
452
- the same directory as our template (` app/components/people-list.js ` ),
453
- and paste in the following content:
454
-
455
- ``` javascript {data-filename="app/components/people-list.js"}
456
- import Component from ' @glimmer/component' ;
457
- import { action } from ' @ember/object' ;
458
-
459
- export default class PeopleListComponent extends Component {
460
- @action
461
- showPerson (person ) {
462
- alert (` The person's name is ${ person} !` );
463
- }
464
- }
465
- ```
466
-
467
- _ Note: If you want this file created for you, you may pass the ` -gc ` flag when running the component generator._
468
-
469
- Here, we created a basic component class and added a method that accepts a
470
- person as an argument and brings up an alert dialog with their name. The
471
- ` @action ` _ decorator_ indicates we want to use this method as an _ action_
472
- in our template, in response to user interaction.
473
-
474
- Now that we have implemented the desired behavior, we can go back to
475
- the component's template and wire everything up:
476
-
477
- ``` handlebars {data-filename="app/components/people-list.hbs" data-diff="-6,+7"}
478
- <h2>{{@title}}</h2>
479
-
480
- <ul>
481
- {{#each @people as |person|}}
482
- <li>
483
- <button type="button">{{person}}</button>
484
- <button type="button" {{on 'click' this.showPerson}}>{{person}}</button>
485
- </li>
486
- {{/each}}
487
- </ul>
488
- ```
489
-
490
- Here, we used the ` on ` _ modifier_ to attach the ` this.showPerson ` action to
491
- the button in the template.
492
-
493
- There is a problem with this though – if you tried this in the browser, you
494
- will quickly discover that clicking on the buttons will bring up an alert
495
- dialog that said "The person's name is ` [Object MouseEvent] ` !" – eek!
496
-
497
- The cause of this bug is that we wrote our action to take an argument – the
498
- person's name – and we forgot to pass it. The fix is easy enough:
499
-
500
- ``` handlebars {data-filename="app/components/people-list.hbs" data-diff="-6,+7"}
501
- <h2>{{@title}}</h2>
502
-
503
- <ul>
504
- {{#each @people as |person|}}
505
- <li>
506
- <button type="button" {{on 'click' this.showPerson}}>{{person}}</button>
507
- <button type="button" {{on 'click' (fn this.showPerson person)}}>{{person}}</button>
508
- </li>
509
- {{/each}}
510
- </ul>
511
- ```
512
-
513
- Instead of passing the action to the ` on ` modifier directly, we used the ` fn `
514
- helper to pass the ` person ` as an argument which our action expects.
515
-
516
- Feel free to try this in the browser. Finally, everything should behave exactly
517
- as we hoped!
518
- </feature-flag-off-template-tag >
519
-
520
- <feature-flag-on-template-tag >
521
-
522
328
Let's use the [ ` on ` modifier] ( ../../components/template-lifecycle-dom-and-modifiers/#toc_event-handlers ) to handle click events on the button:
523
329
524
330
``` gjs {data-filename="app/components/people-list.gjs"}
@@ -600,11 +406,6 @@ export default class extends Component {
600
406
}
601
407
```
602
408
603
- </feature-flag-on-template-tag >
604
-
605
-
606
-
607
-
608
409
## Building For Production
609
410
610
411
Now that we've written our application and verified that it works in development,
0 commit comments