You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/markdown/tutorial/part-1/07-reusable-components.md
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -114,7 +114,7 @@ Let's start with our JavaScript file:
114
114
}
115
115
```
116
116
117
-
Here, we import the access token from the config file and return it from a `token`*[getter][TODO: link to getter]*. This allows us to access our token as `this.token` both inside the `MapComponent` class body, as well as the component's template. It is also important to [URL-encode][TODO: link to URL-encode] the token, just in case it contains any special characters that are not URL-safe.
117
+
Here, we import the access token from the config file and return it from a `token`*[getter](https://javascript.info/property-accessors)*. This allows us to access our token as `this.token` both inside the `MapComponent` class body, as well as the component's template. It is also important to [URL-encode](https://javascript.info/url#encoding-strings) the token, just in case it contains any special characters that are not URL-safe.
118
118
119
119
## Interpolating Values in Templates
120
120
@@ -138,7 +138,7 @@ First, we have a container element for styling purposes.
138
138
139
139
Then we have an `<img>` tag to request and render the static map image from Mapbox.
140
140
141
-
Our template contains several values that don't yet exist—`@lat`, `@lng`, `@zoom`, `@width`, and `@height`. These are *[arguments][TODO: link to arguments]* to the `<Map>` component that we will supply when invoking it.
141
+
Our template contains several values that don't yet exist—`@lat`, `@lng`, `@zoom`, `@width`, and `@height`. These are *[arguments](../../../components/component-arguments-and-html-attributes/#toc_arguments)* to the `<Map>` component that we will supply when invoking it.
142
142
143
143
By *[parameterizing][TODO: link to parameterizing]* our component using arguments, we made a reusable component that can be invoked from different parts of the app and customized to meet the needs for those specific contexts. We have already seen this in action when using the `<LinkTo>` component [earlier](../building-pages/); we had to specify a `@route` argument so that it knew what page to navigate to.
144
144
@@ -156,7 +156,7 @@ The `src` attribute interpolates all the required parameters into the URL format
156
156
157
157
Finally, since we are using the `@2x` "retina" image, we should specify the `width` and `height` attributes. Otherwise, the `<img>` will be rendered at twice the size than what we expected!
158
158
159
-
We just added a lot of behavior into a single component, so let's write some tests! In particular, we should make sure to have some *[test coverage][TODO: link to test coverage]* for the overriding-HTML-attributes behavior we discussed above.
159
+
We just added a lot of behavior into a single component, so let's write some tests! In particular, we should make sure to have some *[test coverage](../../../testing/)* for the overriding-HTML-attributes behavior we discussed above.
@@ -238,7 +238,7 @@ We just added a lot of behavior into a single component, so let's write some tes
238
238
});
239
239
```
240
240
241
-
Note that the `hasAttribute` test helper from [`qunit-dom`][TODO: link to qunit-dom] supports using *[regular expressions][TODO: link to regular expressions]*. We used this feature to confirm that the `src` attribute starts with `https://api.mapbox.com/`, as opposed to requiring it to be an exact match against a string. This allows us to be reasonably confident that the code is working correctly, without being overly-detailed in our tests.
241
+
Note that the `hasAttribute` test helper from [`qunit-dom`](https://github.com/simplabs/qunit-dom/blob/master/API.md) supports using *[regular expressions](https://javascript.info/regexp-introduction)*. We used this feature to confirm that the `src` attribute starts with `https://api.mapbox.com/`, as opposed to requiring it to be an exact match against a string. This allows us to be reasonably confident that the code is working correctly, without being overly-detailed in our tests.
242
242
243
243
*Fingers crossed...* Let's run our tests.
244
244
@@ -356,7 +356,7 @@ Note that we did not mark our getter as `@tracked`. Unlike instance variables, g
356
356
357
357
That being said, the values *produced* by getters can certainly change. In our case, the value produced by our `src` getter depends on the values of `lat`, `lng`, `width`, `height` and `zoom` from `this.args`. Whenever these *[dependencies][TODO: link to dependencies]* get updated, we would expect `{{this.src}}` from our template to be updated accordingly.
358
358
359
-
Ember does this by automatically tracking any variables that were accessed while computing a getter's value. As long as the dependencies themselves are marked as `@tracked`, Ember knows exactly when to invalidate and re-render any templates that may potentially contain any "stale" and outdated getter values. This feature is also known as *[auto-track][TODO: link to auto-track]*. All arguments that can be accessed from `this.args` (in other words, `this.args.*`) are implicitly marked as `@tracked` by the Glimmer component superclass. Since we inherited from that superclass, everything Just Works™.
359
+
Ember does this by automatically tracking any variables that were accessed while computing a getter's value. As long as the dependencies themselves are marked as `@tracked`, Ember knows exactly when to invalidate and re-render any templates that may potentially contain any "stale" and outdated getter values. This feature is also known as *[auto-track](../../../in-depth-topics/autotracking-in-depth/)*. All arguments that can be accessed from `this.args` (in other words, `this.args.*`) are implicitly marked as `@tracked` by the Glimmer component superclass. Since we inherited from that superclass, everything Just Works™.
360
360
361
361
## Getting JavaScript Values into the Test Context
Copy file name to clipboardExpand all lines: src/markdown/tutorial/part-1/08-working-with-data.md
+8-8Lines changed: 8 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -24,7 +24,7 @@ So far, we've been hard-coding everything into our `<Rental>` component. But tha
24
24
25
25
We want to start working towards a place where we can eventually fetch data from the server, and then render the requested data as dynamic content from the templates. In order to do that, we will need a place where we can write the code for fetching data and loading it into the routes.
26
26
27
-
In Ember, *[route files][TODO: link to route files]* are the place to do that. We haven't needed them yet, because all our routes are essentially just rendering static pages up until this point, but we are about to change that.
27
+
In Ember, *[route files](../../../routing/defining-your-routes/)* are the place to do that. We haven't needed them yet, because all our routes are essentially just rendering static pages up until this point, but we are about to change that.
28
28
29
29
Let's start by creating a route file for the index route. We will create a new file at `app/routes/index.js` with the following content:
There's a lot happening here that we haven't seen before, so let's walk through this. First, we're importing the *[`Route` class][TODO: link to Route class]* into the file. This class is used as a starting point for adding functionality to a route, such as loading data.
54
+
There's a lot happening here that we haven't seen before, so let's walk through this. First, we're importing the *[`Route` class](https://api.emberjs.com/ember/release/classes/Route)* into the file. This class is used as a starting point for adding functionality to a route, such as loading data.
55
55
56
-
Then, we are extending the `Route` class into our *own*`IndexRoute`, which we also *[`export`][TODO: link to export]* so that the rest of the application can use it.
56
+
Then, we are extending the `Route` class into our *own*`IndexRoute`, which we also *[`export`](https://javascript.info/import-export#export-default)* so that the rest of the application can use it.
57
57
58
58
## Returning Local Data from the Model Hook
59
59
60
-
So far, so good. But what's happening inside of this route class? We implemented an *[async method][TODO: link to async method]* called `model()`. This method is also known as the *[model hook][TODO: link to model hook]*.
60
+
So far, so good. But what's happening inside of this route class? We implemented an *[async](https://developer.mozilla.org/docs/Learn/JavaScript/Asynchronous/Concepts)*method called `model()`. This method is also known as the *[model hook][TODO: link to model hook]*.
61
61
62
-
The model hook is responsible for fetching and preparing any data that you need for your route. Ember will automatically call this hook when entering a route, so that you can have an opportunity to run your own code to get the data you need. The object returned from this hook is known as the *[model][TODO: link to model]* for the route (surprise!).
62
+
The model hook is responsible for fetching and preparing any data that you need for your route. Ember will automatically call this hook when entering a route, so that you can have an opportunity to run your own code to get the data you need. The object returned from this hook is known as the *[model](../../../routing/specifying-a-routes-model/)* for the route (surprise!).
63
63
64
64
Usually, this is where we'd fetch data from a server. Since fetching data is usually an asynchronous operation, the model hook is marked as `async`. This gives us the option of using the `await` keyword to wait for the data fetching operations to finish.
65
65
66
-
We'll get to that bit later on. At the moment, we are just returning the same hard-coding model data, extracted from the `<Rental>` component, but in a JavaScript object (also known as *[POJO][TODO: link to POJO]*) format.
66
+
We'll get to that bit later on. At the moment, we are just returning the same hard-coding model data, extracted from the `<Rental>` component, but in a *[JavaScript object](https://developer.mozilla.org/docs/Learn/JavaScript/Objects/Basics)* format.
67
67
68
68
## Accessing Route Models from Templates
69
69
@@ -284,7 +284,7 @@ First off, we're using the browser's *[Fetch API](https://developer.mozilla.org/
284
284
285
285
As mentioned above, fetching data from the server is usually an asynchronous operation. The Fetch API takes this into account, which is why `fetch` is an `async`function, just like our model hook. To consume its response, we will have to pair it with the `await` keyword.
286
286
287
-
The Fetch API returns a *[response object][TODO: link to response object]* asynchronously. Once we have this object, we can convert the server's response into whatever format we need; in our case, we knew the server sent the data using the JSON format, so we can use the `json()` method to *[parse][TODO: link to parse]* the response data accordingly. Parsing the response data is *also* an asynchronous operation, so we'll just use the `await` keyword here, too.
287
+
The Fetch API returns a *[response object](https://developer.mozilla.org/docs/Web/API/Response)* asynchronously. Once we have this object, we can convert the server's response into whatever format we need; in our case, we knew the server sent the data using the JSON format, so we can use the `json()` method to *[parse](https://developer.mozilla.org/docs/Web/API/Body/json)* the response data accordingly. Parsing the response data is *also* an asynchronous operation, so we'll just use the `await` keyword here, too.
288
288
289
289
```run:command hidden=true cwd=super-rentals
290
290
git add app/routes/index.js
@@ -297,7 +297,7 @@ Before we go any further, let's pause for a second to look at the server's data
This data follows the *[JSON:API][TODO: link to JSON:API]* format, which is *slightly* different than the hard-coded data that we were returning from the model hook before.
300
+
Thisdatafollowsthe*[JSON:API](https://jsonapi.org/)* format, which is *slightly* different than the hard-coded data that we were returning from the model hook before.
301
301
302
302
First off, the JSON:API format returns an array nested under the `"data"` key, rather than just the data for a single rental property. If we think about this, though, it makes sense; we now want to show a whole list of rental properties that are coming from our server, not just one, so an array of rental property objects is just what we need.
Copy file name to clipboardExpand all lines: src/markdown/tutorial/part-2/09-route-params.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -28,7 +28,7 @@ But first things first: we need to add a route for this new page. We can do that
28
28
});
29
29
```
30
30
31
-
Notice that we are doing something a little different here. Instead of using the default path (`/rental`), we're specifying a custom path. Not only are we using a custom path, but we're also passing in a `:rental_id`, which is what we call a *[dynamic segment][TODO: link to dynamic segment]*. When these routes are evaluated, the `rental_id` will be substituted with the `id` of the individual rental property that we are trying to navigate to.
31
+
Notice that we are doing something a little different here. Instead of using the default path (`/rental`), we're specifying a custom path. Not only are we using a custom path, but we're also passing in a `:rental_id`, which is what we call a *[dynamic segment](../../../routing/defining-your-routes/#toc_dynamic-segments)*. When these routes are evaluated, the `rental_id` will be substituted with the `id` of the individual rental property that we are trying to navigate to.
0 commit comments