Skip to content

Commit

Permalink
Use @model named argument from route templates
Browse files Browse the repository at this point in the history
  • Loading branch information
chancancode committed Sep 7, 2019
1 parent 9a34853 commit 025ccf1
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 42 deletions.
2 changes: 1 addition & 1 deletion guides/release/components/glimmer-components-dom.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Assuming an `article` route with a model that looks like:
This component would be invoked this way:

```handlebars {data-filename=app/templates/article.hbs}
<Article @title={{model.title}} @body={{model.title}}>
<Article @title={{@model.title}} @body={{@model.title}}>
```

The first time the `Article` component is rendered, it would produce this output:
Expand Down
8 changes: 4 additions & 4 deletions guides/release/getting-started/core-concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ to its template:
{{!-- The model for this route is the current user --}}
<div>
Hi <img src="{{this.model.profileImage}}" alt="{{this.model.name}}'s profile picture"> {{this.model.name}},
Hi <img src="{{@model.profileImage}}" alt="{{@model.name}}'s profile picture"> {{@model.name}},
this is a valid Ember template!
</div>
{{#if this.model.isAdmin}}
{{#if @model.isAdmin}}
<div>Remember, with great power comes great responsibility!</div>
{{/if}}
```
Expand Down Expand Up @@ -96,10 +96,10 @@ This allows us to simplify the original template into this:
{{!-- The model for this route is the current user --}}
<div>
Hi <UserProfile @user={{this.model}} /> this is a valid Ember template!
Hi <UserProfile @user={{@model}} /> this is a valid Ember template!
</div>
{{#if this.model.isAdmin}}
{{#if @model.isAdmin}}
<div>Remember, with great power comes great responsibility!</div>
{{/if}}
```
Expand Down
8 changes: 4 additions & 4 deletions guides/release/getting-started/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ Open the `scientists` template and add the following code to loop through the ar
<h2>List of Scientists</h2>
<ul>
{{#each this.model as |scientist|}}
{{#each @model as |scientist|}}
<li>{{scientist}}</li>
{{/each}}
</ul>
Expand Down Expand Up @@ -211,17 +211,17 @@ We're going to tell our component:

1. What title to use, via the `@title` argument.
2. What array of people to use, via the `@people` argument. We'll
provide this route's `model` as the list of people.
provide this route's `@model` as the list of people.

```handlebars {data-filename="app/templates/scientists.hbs" data-diff="-1,-2,-3,-4,-5,-6,-7,+8"}
<h2>List of Scientists</h2>
<ul>
{{#each this.model as |scientist|}}
{{#each @model as |scientist|}}
<li>{{scientist}}</li>
{{/each}}
</ul>
<PeopleList @title="List of Scientists" @people={{this.model}} />
<PeopleList @title="List of Scientists" @people={{@model}} />
```

Go back to your browser and you should see that the UI looks identical.
Expand Down
2 changes: 1 addition & 1 deletion guides/release/models/defining-models.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,5 +177,5 @@ and accessing them within a template:
```

```handlebars
{{this.model.location.latitude}}
{{@model.location.latitude}}
```
16 changes: 8 additions & 8 deletions guides/release/routing/controllers.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ The `BlogPost` model would have properties like:
In the example below, we can see how the template is using the model properties to display some data.

```handlebars {data-filename=app/templates/blog-post.hbs}
<h1>{{this.model.title}}</h1>
<h2>by {{this.model.author}}</h2>
<h1>{{@model.title}}</h1>
<h2>by {{@model.author}}</h2>
<div class="intro">
{{this.model.intro}}
{{@model.intro}}
</div>
<hr>
<div class="body">
{{this.model.body}}
{{@model.body}}
</div>
```

Expand All @@ -74,18 +74,18 @@ export default class BlogPostController extends Controller {
The property `isExpanded` keeps track if the user has expanded the body or not. The action `toggleBody()` provides a way for the user to provide their setting. Both of them are used in the updated template below.

```handlebars {data-filename=app/templates/blog-post.hbs}
<h1>{{this.model.title}}</h1>
<h2>by {{this.model.author}}</h2>
<h1>{{@model.title}}</h1>
<h2>by {{@model.author}}</h2>
<div class='intro'>
{{this.model.intro}}
{{@model.intro}}
</div>
<hr>
{{#if this.isExpanded}}
<button {{on "click" this.toggleBody}}>Hide Body</button>
<div class="body">
{{this.model.body}}
{{@model.body}}
</div>
{{else}}
<button {{on "click" this.toggleBody}}>Show Body</button>
Expand Down
34 changes: 14 additions & 20 deletions guides/release/routing/specifying-a-routes-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,11 @@ export default class FavoritePostsRoute extends Route {

`model` hooks have some special powers:

1. When you return data from this model, it becomes automatically available in the route's `.hbs` file as `this.model`
2. A `model` hook can return just about any type of data, like a string, object, or array, but the most common pattern is to return a JavaScript [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises)
3. If you return a Promise from the model hook, your route will wait for the Promise to resolve before it renders the template
1. When you return data from this model, it becomes automatically available in the route's `.hbs` file as `@model` and in the route's controller as `this.model`.
2. A `model` hook can return just about any type of data, like a string, object, or array, but the most common pattern is to return a JavaScript [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises).
3. If you return a Promise from the model hook, your route will wait for the Promise to resolve before it renders the template.
4. Since the `model` hook is Promise-aware, it is great for making API requests (using tools like [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)) and returning the results.
5. When using the `model` hook to load data, you can take advantage of other niceties that Ember provides, like
[automatic route transitions](../preventing-and-retrying-transitions/)
after the data is returned,
[loading screens, error handling](../loading-and-error-substates/),
and more
5. When using the `model` hook to load data, you can take advantage of other niceties that Ember provides, like [automatic route transitions](../preventing-and-retrying-transitions/) after the data is returned, [loading screens, error handling](../loading-and-error-substates/), and more.
6. The `model` hook may automatically re-run in certain conditions, as you'll read about below.

## Using the `model` hook
Expand All @@ -57,18 +53,16 @@ export default class FavoritePostsRoute extends Route {
}
```

Now that data can be used in the `favorite-posts` template:
Now that data can be used in the `favorite-posts` template:

```handlebars {data-filename=app/templates/favorite-posts.hbs}
{{#each this.model as |post|}}
{{#each @model as |post|}}
<div>
{{post.title}}
</div>
{{/each}}
```

Behind the scenes, what is happening is that the [route's controller](http://api.emberjs.com/ember/release/classes/Route/methods/model?anchor=setupController) receives the results of the model hook, and makes those results available to the template. Your app may not have a controller file for the route, but the behavior is the same regardless.

Let's compare some examples using the model hook to make asynchronous HTTP requests to a server somewhere.

### Fetch example
Expand Down Expand Up @@ -107,7 +101,7 @@ was passed a model):

```handlebars {data-filename=app/templates/photos.hbs}
<h1>Photos</h1>
{{#each this.model.photos as |photo|}}
{{#each @model.photos as |photo|}}
<p>
<LinkTo @route="photo" @model={{photo}}>
<img src="{{photo.thumbnailUrl}}" alt="{{photo.title}}" />
Expand All @@ -121,7 +115,7 @@ identifier, instead):

```handlebars {data-filename=app/templates/photos.hbs}
<h1>Photos</h1>
{{#each this.model.photos as |photo|}}
{{#each @model.photos as |photo|}}
<p>
<LinkTo @route="photo" @model={{photo.id}}>
<img src="{{photo.thumbnailUrl}}" alt="{{photo.title}}" />
Expand Down Expand Up @@ -180,15 +174,15 @@ each record in the song model and album model:
<h1>Playlist</h1>
<ul>
{{#each this.model.songs as |song|}}
{{#each @model.songs as |song|}}
<li>{{song.name}} by {{song.artist}}</li>
{{/each}}
</ul>
<h1>Albums</h1>
<ul>
{{#each this.model.albums as |album|}}
{{#each @model.albums as |album|}}
<li>{{album.title}} by {{album.artist}}</li>
{{/each}}
</ul>
Expand Down Expand Up @@ -246,7 +240,7 @@ When you provide a string or number to the `link-to`, the dynamic segment's `mod
In this example, `photo.id` might have an id of `4`:

```handlebars
{{#each model as |photo|}}
{{#each @model as |photo|}}
{{#link-to "photo" photo.id}}
link text to display
{{/link-to}}
Expand All @@ -259,7 +253,7 @@ For this reason, many Ember developers choose to pass only ids to `{{link-to}}`
Here's what it looks like to pass the entire `photo` record:

```handlebars
{{#each model as |photo|}}
{{#each @model as |photo|}}
{{#link-to "photo" photo}}
link text to display
{{/link-to}}
Expand Down Expand Up @@ -345,10 +339,10 @@ And calling `modelFor` returned the result of the `model` hook.

If you are having trouble getting a model's data to show up in the template, here are some tips:

- Use the [`{{debugger}}`](https://api.emberjs.com/ember/release/classes/Ember.Templates.helpers/methods/debugger?anchor=debugger) or [`{{log}}`](https://api.emberjs.com/ember/release/classes/Ember.Templates.helpers/methods/debugger?anchor=log) helper to inspect the `{{model}}` from the template
- Use the [`{{debugger}}`](https://api.emberjs.com/ember/release/classes/Ember.Templates.helpers/methods/debugger?anchor=debugger) or [`{{log}}`](https://api.emberjs.com/ember/release/classes/Ember.Templates.helpers/methods/debugger?anchor=log) helper to inspect the `{{@model}}` from the template
- return hard-coded sample data as a test to see if the problem is really in the model hook, or elsewhere down the line
- study JavaScript Promises in general, to make sure you are returning data from the Promise correctly
- make sure your `model` hook has a `return` statement
- check to see whether the data returned from a `model` hook is an object, array, or JavaScript Primitive. For example, if the result of `model` is an array, using `{{this.model}}` in the template won't work. You will need to iterate over the array with an [`{{#each}}`](https://api.emberjs.com/ember/release/classes/Ember.Templates.helpers/methods/each?anchor=each) helper. If the result is an object, you need to access the individual attribute like `{{this.model.title}}` to render it in the template.
- check to see whether the data returned from a `model` hook is an object, array, or JavaScript Primitive. For example, if the result of `model` is an array, using `{{@model}}` in the template won't work. You will need to iterate over the array with an [`{{#each}}`](https://api.emberjs.com/ember/release/classes/Ember.Templates.helpers/methods/each?anchor=each) helper. If the result is an object, you need to access the individual attribute like `{{@model.title}}` to render it in the template.
- use your browser's development tools to examine the outgoing and incoming API responses and see if they match what your code expects
- If you are using Ember Data, use the [Ember Inspector](../../ember-inspector/) browser plugin to explore the View Tree/Model and Data sections.
4 changes: 2 additions & 2 deletions guides/release/state-management/tracked-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,8 @@ export default class ApplicationController extends Controller {
}
```

```js {data-filename=app/templates/application.hbs}
{{this.model.fullName}}
```handlebars {data-filename=app/templates/application.hbs}
{{@model.fullName}}
<button {{on "click" (fn this.updateName 'Krati' 'Ahuja')}}>
Update Name
Expand Down
4 changes: 2 additions & 2 deletions guides/release/templates/writing-helpers.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ To use the `format-currency` helper, you call it using curly braces in
your template:

```handlebars
Your total is {{format-currency this.model.totalDue}}.
Your total is {{format-currency @model.totalDue}}.
```

Let's now implement the helper. Helpers are functions that take
Expand Down Expand Up @@ -361,7 +361,7 @@ For example, imagine that we have a chat app and use our `make-bold`
helper to welcome the new users into the channel:

```handlebars
Welcome back! {{make-bold this.model.firstName}} has joined the channel.
Welcome back! {{make-bold @model.firstName}} has joined the channel.
```

Now a malicious user simply needs to set their `firstName` to a string
Expand Down

0 comments on commit 025ccf1

Please sign in to comment.