From a690cd369a8ff9e6607c5d07b8faf33f4bb8eae3 Mon Sep 17 00:00:00 2001 From: Chris Garrett Date: Mon, 18 Mar 2019 16:27:10 -0700 Subject: [PATCH 1/4] [OCTANE] Editting Pass --- .../components/arguments-and-attributes.md | 16 +- .../components/defining-a-component.md | 35 ++-- guides/release/components/displaying-data.md | 99 ---------- guides/release/components/handling-events.md | 176 ------------------ .../wrapping-content-in-a-component.md | 115 ------------ guides/release/components/yields.md | 8 +- .../release/getting-started/core-concepts.md | 6 +- guides/release/getting-started/quick-start.md | 14 +- .../state-management/tracked-properties.md | 4 +- guides/release/templates/built-in-helpers.md | 10 +- guides/release/templates/handlebars-basics.md | 7 +- guides/release/tutorial/ember-data.md | 14 +- .../classic-classes.md | 67 +++---- .../working-with-javascript/native-classes.md | 2 +- .../native-vs-classic-class-cheatsheet.md | 26 +-- 15 files changed, 93 insertions(+), 506 deletions(-) delete mode 100644 guides/release/components/displaying-data.md delete mode 100644 guides/release/components/handling-events.md delete mode 100644 guides/release/components/wrapping-content-in-a-component.md diff --git a/guides/release/components/arguments-and-attributes.md b/guides/release/components/arguments-and-attributes.md index a85ed7b461..6548592e31 100644 --- a/guides/release/components/arguments-and-attributes.md +++ b/guides/release/components/arguments-and-attributes.md @@ -234,25 +234,33 @@ a class than completely override the existing ones. For `class`, the order of `...attributes` will determine the order of merging. Putting it before: ```handlebars -

Hello {{@friend}}, I'm {{this.name}}!

+

+ Hello {{@friend}}, I'm {{this.name}}! +

``` Results in: ```html -

Hello {{@friend}}, I'm {{this.name}}!

+

+ Hello {{@friend}}, I'm {{this.name}}! +

``` And putting it after: ```handlebars -

Hello {{@friend}}, I'm {{this.name}}!

+

+ Hello {{@friend}}, I'm {{this.name}}! +

``` Results in: ```html -

Hello {{@friend}}, I'm {{this.name}}!

+

+ Hello {{@friend}}, I'm {{this.name}}! +

``` #### Attributes and Modifiers diff --git a/guides/release/components/defining-a-component.md b/guides/release/components/defining-a-component.md index 26402a73b7..9d7a89e810 100644 --- a/guides/release/components/defining-a-component.md +++ b/guides/release/components/defining-a-component.md @@ -48,7 +48,7 @@ ember generate component blog-post This will create a few different files: -``` +```bash installing component create app/components/blog-post.js create app/templates/components/blog-post.hbs @@ -136,10 +136,9 @@ Here, we have two different kinds of dynamic values: `{{this}}` always refers to that instance, and allows you to access methods, fields, and other properties on the class instance. -We say that these values are _bound_ to the template in those locations. It's -important to note that arguments and properties can be used interchangeably, so -we could for instance have used an argument for the `sectionClass`, and a -class property for title or post content: +It's important to note that arguments and properties can be used +interchangeably, so we could for instance have used an argument for the +`sectionClass`, and a class property for title or post content: ```handlebars {data-filename=app/templates/components/blog-post.hbs}

{{this.title}}

@@ -148,13 +147,11 @@ class property for title or post content: ``` -Both arguments and properties can be used in any valid binding location. For -more details on where and how you can bind values, read through the +For more details on where and how you can invoke values, read through the [section on templating](../../templates/handlebars-basics/). -The reason you would choose an argument or -property is based on how you expect to use the component, and whether or not the -value should be based on internal logic within the component, or values passed -to the component where it is used. +The reason you would choose an argument or property is based on how you expect +to use the component, and whether or not the value should be based on internal +logic within the component, or values passed to the component where it is used. You can also use template helpers, modifiers, and other components within your component template: @@ -207,7 +204,8 @@ And this will place the block - the text that is in between `` and ```html

Fun Facts About Tomster

- 1. He's a hamster! 2. But also a Tomster! + 1. He's a hamster! + 2. But also a Tomster!
``` @@ -255,8 +253,8 @@ or functional components, and their major difference is that they do not have an _instance_ or any instance state. What this means in practice is that using properties in the template -(`{{this.myProperty}}`) will result in an error. In a template-only component -you can only use arguments (`{{@myArgument}}`). +(e.g. `{{this.myProperty}}`) will result in an error. In a template-only component +you can only use arguments (e.g. `{{@myArgument}}`). Template-Only components are useful for components that don't need to have their own state, such as components that focus on presentation and formatting of data. @@ -343,7 +341,7 @@ known as _actions_, and are decorated with the `@action` decorator.
{{yield}} -
@@ -368,7 +366,8 @@ export default class HelloButton extends Component { ``` Any method that you use in a template should be decorated with this decorator. -It'll be covered in more detail in the section on [Actions](../actions). +It'll be covered in more detail in the section on [Actions and +Events](../actions-and-events). #### Component Hooks and Properties @@ -376,8 +375,8 @@ Components have the following class signature (this given as a TypeScript class signature for clarity and brevity, if you don't know TypeScript, don't worry! We'll explain what it all means in just a minute): -```ts -declare class GlimmerComponent { +```js +class GlimmerComponent { args: object; isDestroying: boolean; diff --git a/guides/release/components/displaying-data.md b/guides/release/components/displaying-data.md deleted file mode 100644 index 1b94b725ec..0000000000 --- a/guides/release/components/displaying-data.md +++ /dev/null @@ -1,99 +0,0 @@ -In a component template you can display two types of value, -properties of the component object, -or values passed into the component. - -To use a property you prefix it with `this`, like so: - -```handlebars -

I'm {{this.name}}!

-``` - -And to use a named argument you prefix it with `@`, like so: - -```handlebars -

Hello {{@friend}}!

-``` - -Since properties and named arguments are visually different, -this syntax allows you to know where a value comes from when you are reading the template. -If you encounter the `{{this.name}}` syntax, -you know you should check the JavaScript file of the component. -If you encounter the `{{@friend}}` syntax, -you know that the value is passed to the component when it is used in another template. - -## Properties - -To display a component property in the template, you prefix it with `this`, -like you would in JavaScript. - -For the example, we will build a `Greeting` component with a hard-coded name. -Then, we will use that property in the component template: - -```javascript {data-filename=app/components/greeting.js} -import Component from '@glimmer/component'; - -export default class Greeting extends Component { - constructor() { - super(...arguments); - - this.name = "Tomster"; - } -} -``` - -```handlebars {data-filename=app/templates/components/greeting.hbs} -

Hello World, I'm {{this.name}}!

-``` - -This renders: - -``` -

Hello World, I'm Tomster!

-``` - -## Named arguments - -A named argument is a value passed to the component when invoking it. -If you see: - -```javascript - -``` - -Then you know that the `Greeting` component is being invoked. -We are passing `friend` (named argument) to it with the value `Zoey`. - -We will use the component from the previous example: - -```javascript -import Component from '@glimmer/component'; - -export default class Greeting extends Component { - constructor() { - super(...arguments); - - this.name = "Tomster"; - } -} -``` - -But change the template so that instead of having `Hello World` hard-coded, -we will display the `friend` named property: - -```handlebars -

Hello {{@friend}}, I'm {{this.name}}!

-``` - -Now, when we call the `Greeting` component like so: - -```handlebars - -``` - -The output will be: - -```html -

Hello Zoey, I'm Tomster!

-``` - -For more detailed information see [Passing arguments and HTML attributes](./arguments-and-attributes). diff --git a/guides/release/components/handling-events.md b/guides/release/components/handling-events.md deleted file mode 100644 index 590de7cfd7..0000000000 --- a/guides/release/components/handling-events.md +++ /dev/null @@ -1,176 +0,0 @@ -You can respond to user events on your component like double-clicking, hovering, -and key presses through event handlers. Simply implement the name of the event -you want to respond to as a method on your component. - -For example, imagine we have a template like this: - -```handlebars - - This is a double clickable area! - -``` - -Let's implement `DoubleClickable` such that when it is -clicked, an alert is displayed: - -```javascript {data-filename=app/components/double-clickable.js} -import Component from '@ember/component'; - -export default Component.extend({ - doubleClick() { - alert('DoubleClickableComponent was clicked!'); - } -}); -``` - -Browser events may bubble up the DOM which potentially target parent component(s) -in succession. To enable bubbling `return true;` from the event handler method -in your component. - -```javascript {data-filename=app/components/double-clickable.js} -import Component from '@ember/component'; -import Ember from 'ember'; - -export default Component.extend({ - doubleClick() { - console.info('DoubleClickableComponent was clicked!'); - return true; - } -}); -``` - -See the list of event names at the end of this page. Any event can be defined -as an event handler in your component. - -## Sending Actions - -In some cases your component needs to define event handlers, perhaps to support -various draggable behaviors. For example, a component may need to send an `id` -when it receives a drop event: - -```handlebars - -``` - -You can define the component's event handlers to manage the drop event. -And if you need to, you may also stop events from bubbling, by using -`return false;`. - -```javascript {data-filename=app/components/drop-target.js} -import Component from '@ember/component'; - -export default Component.extend({ - attributeBindings: ['draggable'], - draggable: 'true', - - dragOver() { - return false; - }, - - drop(event) { - let id = event.dataTransfer.getData('text/data'); - this.dropAction(id); - } -}); -``` - -In the above component, `didDrop` is the `action` passed in. This action is -called from the `drop` event handler and passes one argument to the action - -the `id` value found through the `drop` event object. - - -Another way to preserve native event behaviors and use an action, is to -assign a (closure) action to an inline event handler. Consider the -template below which includes an `onclick` handler on a `button` element: - -```handlebars - -``` - -The `signUp` action is simply a function defined on the `actions` hash -of a component. Since the action is assigned to an inline handler, the -function definition can define the event object as its first parameter. - -```javascript -actions: { - signUp(event){ - // Only when assigning the action to an inline handler, the event object - // is passed to the action as the first parameter. - } -} -``` - -The normal behavior for a function defined in `actions` does not receive the -browser event as an argument. So, the function definition for the action cannot -define an event parameter. The following example demonstrates the -default behavior using an action. - -```handlebars - -``` - -```javascript -actions: { - signUp() { - // No event object is passed to the action. - } -} -``` - -To utilize an `event` object as a function parameter: - -- Define the event handler in the component (which is designed to receive the - browser event object). -- Or, assign an action to an inline event handler in the template (which - creates a closure action and does receive the event object as an argument). - - -## Event Names - -The event handling examples described above respond to one set of events. -The names of the built-in events are listed below. Custom events can be -registered by using [Application.customEvents](https://www.emberjs.com/api/ember/release/classes/Application/properties/customEvents?anchor=customEvents). - -Touch events: - -* `touchStart` -* `touchMove` -* `touchEnd` -* `touchCancel` - -Keyboard events - -* `keyDown` -* `keyUp` -* `keyPress` - -Mouse events - -* `mouseDown` -* `mouseUp` -* `contextMenu` -* `click` -* `doubleClick` -* `mouseMove` -* `focusIn` -* `focusOut` -* `mouseEnter` -* `mouseLeave` - -Form events: - -* `submit` -* `change` -* `focusIn` -* `focusOut` -* `input` - -HTML5 drag and drop events: - -* `dragStart` -* `drag` -* `dragEnter` -* `dragLeave` -* `dragOver` -* `dragEnd` -* `drop` diff --git a/guides/release/components/wrapping-content-in-a-component.md b/guides/release/components/wrapping-content-in-a-component.md deleted file mode 100644 index 38d4189715..0000000000 --- a/guides/release/components/wrapping-content-in-a-component.md +++ /dev/null @@ -1,115 +0,0 @@ -Sometimes, you may want to define a component that wraps content provided by other templates. - -For example, imagine we are building a `BlogPost` component that we can use in our application to display a blog post: - -```handlebars {data-filename=app/templates/components/blog-post.hbs} -

{{this.title}}

-
{{this.body}}
-``` - -Now, we can use the `` component and pass it properties in another template: - -```handlebars - -``` - -See -[Passing Properties to a Component](../arguments-and-attributes/) -for more. - -In this case, the content we wanted to display came from the model. -But what if we want the developer using our component to be able to provide custom HTML content? - -In addition to the simple form you've learned so far, -components also support being used in **block form**. -In block form, components can be passed a Handlebars template that is rendered inside the component's template wherever the `{{yield}}` expression appears. - -To use the block form, change the self-closing tag to a separate opening and closing tag: `` - -In that case, we can use the `` component in **block form** and tell Ember where the block content should be rendered using the `{{yield}}` helper. -To update the example above, we'll first change the component's template: - -```handlebars {data-filename=app/templates/components/blog-post.hbs} -

{{this.title}}

-
{{yield}}
-``` - -You can see that we've replaced `{{this.body}}` with `{{yield}}`. -This tells Ember that this content will be provided when the component is used. - -Next, we'll update the template using the component to use the block form: - -```handlebars {data-filename=app/templates/index.hbs} - -

by {{this.author}}

- {{this.body}} -
-``` - -It's important to note that the template scope inside the component block is the same as outside. -If a property is available in the template outside the component, it is also available inside the component block. - -## Sharing Component Data with its Wrapped Content - -There is also a way to share data within your blog post component with the content it is wrapping. -In our blog post component we want to provide a way for the user to configure what type of style they want to write their post in. -We will give them the option to specify either `markdown-style` or `html-style`. - -```handlebars {data-filename=app/templates/index.hbs} - -

by {{this.author}}

- {{this.body}} -
-``` - -Supporting different editing styles will require different body components to provide special validation and highlighting. -To load a different body component based on editing style, -you can yield the component using the [`component helper`](https://www.emberjs.com/api/ember/release/classes/Ember.Templates.helpers/methods/component?anchor=component) and [`hash helper`](https://www.emberjs.com/api/ember/release/classes/Ember.Templates.helpers/methods/hash?anchor=hash). -Here, the appropriate component is assigned to a hash using nested helpers and yielded to the template. -Notice `editStyle` being used as an argument to the component helper. - -```handlebars {data-filename=app/templates/components/blog-post.hbs} -

{{this.title}}

-
{{yield (hash body=(component this.editStyle))}}
-``` - -Once yielded, the data can be accessed by the wrapped content by referencing the `post` variable. -Now a component called `markdown-style` will be rendered in `{{post.body}}`. - -```handlebars {data-filename=app/templates/index.hbs} - -

by {{this.author}}

- {{post.body}} -
-``` - -Finally, we need to share `myText` with the body in order to have it display. -To pass the blog text to the body component, we'll add a `postData` argument to the component helper. - -```handlebars {data-filename=app/templates/components/blog-post.hbs} -

{{this.title}}

-
- {{yield (hash - body=(component this.editStyle postData=this.postData) - )}} -
-``` - -At this point, our block content has access to everything it needs to render, -via the wrapping `blog-post` component's template helpers. - -Additionally, since the component isn't instantiated until the block content is rendered, -we can add arguments within the block. -In this case we'll add a text style option which will dictate the style of the body text we want in our post. -When `{{post.body}}` is instantiated, it will have both the `editStyle` and `postData` given by its wrapping component, -as well as the `bodyStyle` declared in the template. - -```handlebars {data-filename=app/templates/index.hbs} - -

by {{this.author}}

- {{post.body bodyStyle="compact-style"}} -
-``` - -Components built this way are commonly referred to as "Contextual Components", -allowing inner components to be wrapped within the context of outer components without breaking encapsulation. diff --git a/guides/release/components/yields.md b/guides/release/components/yields.md index 4259f9a953..7db4816c00 100644 --- a/guides/release/components/yields.md +++ b/guides/release/components/yields.md @@ -102,7 +102,7 @@ button: {{/if}} - ``` @@ -135,7 +135,7 @@ What we can do here is _yield_ the `toggleModal` action: {{/if}} - ``` @@ -148,13 +148,13 @@ similar to the `{{each}}` helper, and place the action on their buttons: You have unsaved progress, are you sure you want to quit? ``` diff --git a/guides/release/templates/built-in-helpers.md b/guides/release/templates/built-in-helpers.md index ab7882adc2..cacf90b297 100644 --- a/guides/release/templates/built-in-helpers.md +++ b/guides/release/templates/built-in-helpers.md @@ -32,7 +32,7 @@ helper makes it easy to dynamically send a number of parameters to a component or helper as a single parameter in the format of a concatenated string. ```handlebars -{{get "foo" (concat "item" this.index)}} +{{get this.foo (concat "item" this.index)}} ``` This will display the result of `this.foo.item1` when index is 1, and @@ -84,11 +84,13 @@ Using the [`{{array}}`](https://www.emberjs.com/api/ember/release/classes/Ember. you can pass arrays directly from the template as an argument to your components. ```handlebars - + this.myOtherPerson + }} +/> ``` In the component's template, you can then use the `people` argument as an array: diff --git a/guides/release/templates/handlebars-basics.md b/guides/release/templates/handlebars-basics.md index 8ccdc4ae49..2a7ad0cd13 100644 --- a/guides/release/templates/handlebars-basics.md +++ b/guides/release/templates/handlebars-basics.md @@ -148,7 +148,7 @@ A method named `plantATree` is called when the button is clicked. `plantATree` comes from the JavaScript file associated with the template, like a Component or Controller --> -