@@ -31,7 +31,7 @@ you will have access to a new `ember` command in your terminal.
3131You can use the ` ember new ` command to create a new application.
3232
3333``` bash
34- ember new ember-quickstart --lang en
34+ ember new ember-quickstart --lang en --strict
3535```
3636
3737This 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.
8787
8888## Write some HTML in a template
8989
90- <feature-flag-on-template-tag >
91-
9290We will start by editing the ` application ` template.
9391This template is always on screen while the user has your application loaded.
9492In 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
9997 {{outlet}}
10098</template>
10199```
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 >
117100
118101Ember detects the changed file and automatically reloads the page for you in the background.
119102You should see that the welcome page has been replaced by "PeopleTracker".
@@ -135,21 +118,7 @@ ember generate route scientists
135118
136119You'll see output like this:
137120
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 >
150121``` bash
151- # 🚧 Under construction 🚧
152- # `ember generate route` has not been updated to produce GJS files yet.
153122installing route
154123 create app/routes/scientists.js
155124 create app/templates/scientists.gjs
@@ -158,7 +127,6 @@ updating router
158127installing route-test
159128 create tests/unit/routes/scientists-test.js
160129```
161- </feature-flag-on-template-tag >
162130
163131That is Ember telling you that it has created:
164132
@@ -167,20 +135,7 @@ That is Ember telling you that it has created:
1671353 . An entry in the application's router (located in ` app/router.js ` ).
1681364 . A unit test for this route.
169137
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:
184139
185140``` gjs {data-filename=app/templates/scientists.gjs}
186141import { pageTitle } from 'ember-page-title';
@@ -194,8 +149,6 @@ import { pageTitle } from 'ember-page-title';
194149In your browser, open [ ` http://localhost:4200/scientists ` ] ( http://localhost:4200/scientists ) .
195150You should see the ` <h2> ` we put in the ` scientists.gjs ` template right below the ` <h1> ` from our ` application.gjs ` template.
196151
197- </feature-flag-on-template-tag >
198-
199152Since the scientist route is nested under the application route, Ember will render its content inside the application route template's ` {{outlet}} ` directive.
200153
201154Now that we've got the ` scientists ` template rendering,
@@ -225,19 +178,6 @@ the `model()` method supports any library that uses [JavaScript Promises](https:
225178Now let's tell Ember how to turn that array of strings into HTML.
226179Open the ` scientists ` template and add the following code to loop through the array and print it:
227180
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 >
241181``` gjs {data-filename="app/templates/scientists.gjs"}
242182import { pageTitle } from 'ember-page-title';
243183
@@ -251,7 +191,6 @@ import { pageTitle } from 'ember-page-title';
251191 </ul>
252192</template>
253193```
254- </feature-flag-on-template-tag >
255194
256195Here, we use the ` each ` _ helper_ to loop over each item in the array we
257196provided 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.
275214Make a new component by typing:
276215
277216``` 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>
282217ember generate component people-list
283218```
284219
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:
290221
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
296227```
297228
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
299233
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:
302235
303236``` gjs {data-filename=app/components/people-list.gjs}
304237<template>
@@ -312,8 +245,6 @@ Copy and paste this part of the `scientists` template into the `PeopleList` comp
312245</template>
313246```
314247
315- </feature-flag-on-template-tag >
316-
317248Note that we've changed the title from a hard-coded string ("List of Scientists")
318249to ` {{@title}} ` . The ` @ ` indicates that ` @title ` is an argument that will be
319250passed 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.
322253We've also renamed ` scientist ` to the more-generic ` person ` ,
323254decreasing the coupling of our component to where it's used.
324255
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-
343256Save this template and switch back to the ` scientists ` template.
344257
345258We'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
354267
355268Let's replace all our old code with our new componentized version:
356269
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 >
374270``` gjs {data-filename="app/templates/scientists.gjs" data-diff="+2,-6,-7,-8,-9,-10,-11,+12,+13,+14,+15"}
375271import { pageTitle } from 'ember-page-title';
376272import PeopleList from '../components/people-list';
@@ -389,7 +285,6 @@ import PeopleList from '../components/people-list';
389285 />
390286</template>
391287```
392- </feature-flag-on-template-tag >
393288
394289Go back to your browser and you should see that the UI looks identical.
395290The 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.
407302
408303First, we can modify the ` PeopleList ` component to include a button:
409304
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 >
424305``` gjs {data-filename="app/components/people-list.gjs"}
425306<template>
426307 <h2>{{@title}}</h2>
@@ -434,8 +315,6 @@ First, we can modify the `PeopleList` component to include a button:
434315 </ul>
435316</template>
436317```
437- </feature-flag-on-template-tag >
438-
439318
440319Now that we have a button, we need to wire it up to do _ something_ when a user
441320clicks 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_
446325to our component – handling the button click in this case, we will need to
447326attach some JavaScript to the component.
448327
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-
522328Let's use the [ ` on ` modifier] ( ../../components/template-lifecycle-dom-and-modifiers/#toc_event-handlers ) to handle click events on the button:
523329
524330``` gjs {data-filename="app/components/people-list.gjs"}
@@ -600,11 +406,6 @@ export default class extends Component {
600406}
601407```
602408
603- </feature-flag-on-template-tag >
604-
605-
606-
607-
608409## Building For Production
609410
610411Now that we've written our application and verified that it works in development,
0 commit comments