Skip to content
This repository has been archived by the owner on May 26, 2019. It is now read-only.

Update: Ember cookbook to cli #25

Merged
merged 1 commit into from
Mar 20, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
You are new to Ember, but want to help write the Cookbook.

### Solution
Suggest and/or submit pull requests with a _problem_ statement (see [Suggesting A Recipe](./suggesting_a_recipe)). You do not need to worry about providing a solution or discussion. Someone more experienced with Ember will be able to take your _problem_ and provide a _solution_ and _discussion_.
Suggest and/or submit pull requests with a _problem_ statement (see [Suggesting A Recipe](../suggesting_a_recipe)). You do not need to worry about providing a solution or discussion. Someone more experienced with Ember will be able to take your _problem_ and provide a _solution_ and _discussion_.

### Discussion
The first version of the Ember Cookbook will be completed in a few phases. First, we will be accepting
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Based on your experience and knowledge of Ember, we recommend submitting pull re
<dd><em>Problem</em>, <em>Solution</em> &amp; <em>Discussion</em> is the right way to help if you have a deeper understanding of the topic and can write cogently about why the solution is a good idea, explain pitfalls of other solutions, etc.</dd>
</dl>

You will be able to suggest possible recipes by forking this project and submitting a pull request with a new recipe (see [Suggesting a Recipe][suggesting_a_recipe]).
You will be able to suggest possible recipes by forking this project and submitting a pull request with a new recipe (see [Suggesting a Recipe](../suggesting_a_recipe)).

[fork_repo]: https://github.com/emberjs/website
[suggesting_a_recipe]: ./suggesting_a_recipe
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ You want to base the value of one property on the value of another property.
### Solution
Use one of the computed property macros like `Ember.computed.alias` or `Ember.computed.gte`

```js
App.Person = Ember.Object.extend({
```app/models/person.js
export default Ember.Object.extend({
firstName : null,
lastName : null,
surname : Ember.computed.alias("lastName"),
Expand All @@ -19,5 +19,5 @@ on the values of other properties, correctly connecting them with bindings so th
updated when values change. These all are stored on the `Ember.computed` object
and [documented in the API documentation](http://emberjs.com/api/#method_computed)

#### Example
<a class="jsbin-embed" href="http://emberjs.jsbin.com/AfufoSO/3/edit?output">JS Bin</a>
<!---#### Example
<a class="jsbin-embed" href="http://jsbin.com/tahigobage/4/edit?output">JS Bin</a>-->
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,21 @@ Add google analytic's base code to the html file that renders your ember app.
Then reopen the application router and add this function. It will be called when
`didTransition` is fired by the router.

```js
App.Router.reopen({
```app/router.js
var Router = Ember.Router.extend({
// customization goes here
});

Router.reopen({
notifyGoogleAnalytics: function() {
return ga('send', 'pageview', {
'page': this.get('url'),
'title': this.get('url')
});
}.on('didTransition')
});

export default Router;
```

### Discussion
Expand All @@ -52,4 +58,4 @@ changes, in this example we are getting the path after the hash in the url so we
can notify Google Analytics about moving between areas of the site.


[JSBin Example](http://jsbin.com/xebevu)
<!--[JSBin Example](http://jsbin.com/xebevu)-->
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ Ember.Handlebars.helper('truncate', function(str, len) {
});
```

#### Example
<!--- #### Example

<a class="jsbin-embed" href="http://jsbin.com/APoDiLA/1/embed?js,output">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script>
<a class="jsbin-embed" href="http://jsbin.com/APoDiLA/1/embed?js,output">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script>-->
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@ Write a custom component that renders the Tweet button with specific attributes
passed in.

```handlebars
{{share-twitter data-url="http://emberjs.com"
data-text="EmberJS Components are Amazing!"
data-size="large"
data-hashtags="emberjs"}}

{{share-twitter class='twitter-share-button' href=url
data-text=text
data-size="large"
data-hashtags="emberjs"}}
```

```javascript
App.ShareTwitterComponent = Ember.Component.extend({
```app/components/share-twitter.js
export default Ember.Component.extend({
tagName: 'a',
classNames: 'twitter-share-button',
attributeBindings: ['data-size', 'data-url', 'data-text', 'data-hashtags']
Expand All @@ -25,9 +24,13 @@ App.ShareTwitterComponent = Ember.Component.extend({
Include Twitter's widget code in your HTML:

```javascript
<script type="text/javascript" src="http://platform.twitter.com/widgets.js" id="twitter-wjs"></script>
<script>
window.twttr=(function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return;js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);t._e=[];t.ready=function(f){t._e.push(f);};return t;}(document,"script","twitter-wjs"));
</script>
```

Note: the Twitter api does change from time to time. Refer to the [documents](https://dev.twitter.com/web/tweet-button) if necessary.

### Discussion
Twitter's widget library expects to find an `<a>` tag on the page with specific `data-` attributes applied.
It takes the values of these attributes and, when the `<a>` tag is clicked, opens an iFrame for twitter sharing.
Expand All @@ -42,6 +45,6 @@ attributes will be updated to match the new values.

An appropriate tag and css class are applied through the `tagName` and `classNames` properties.

#### Example
<!---#### Example

<a class="jsbin-embed" href="http://emberjs.jsbin.com/OpocEPu/1/edit?js,output">JS Bin</a>
<a class="jsbin-embed" href="http://jsbin.com/hihoboforo/4/edit?live">JS Bin</a>-->
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,23 @@ Write an Ember Component to change to loading state when action is taking place.

For example a button to save data could be as

```handlebars
<script type='text/x-handlebars' id='application'>
{{spin-button id="forapplication" isLoading = isLoading buttonText=buttonText action='saveData'}}
</script>

<script type='text/x-handlebars' id='components/spin-button'>
<button {{bind-attr id=id}} {{action 'showLoading'}}>
{{#if isLoading}}
<img src="http://i639.photobucket.com/albums/uu116/pksjce/spiffygif_18x18.gif">
{{else}}
{{buttonText}}
{{/if}}
</button>
</script>
```app/templates/application.hbs
{{spin-button id="forapplication" isLoading = isLoading buttonText=buttonText action='saveData'}}
```

```javascript
var App = Ember.Application.create({});
```app/templates/components/spin-button.hbs

<button {{bind-attr id=id}} {{action 'showLoading'}}>
{{#if isLoading}}
<img src="http://i639.photobucket.com/albums/uu116/pksjce/spiffygif_18x18.gif">
{{else}}
{{buttonText}}
{{/if}}
</button>
```

App.ApplicationController = Ember.Controller.extend({
```app/controllers/application.js
export default Ember.Controller.extend({
isLoading:false,
buttonText:"Submit",
actions:{
Expand All @@ -39,8 +36,10 @@ App.ApplicationController = Ember.Controller.extend({
}
}
});
```

App.SpinButtonComponent = Ember.Component.extend({
```app/components/spin-button.js
export default Ember.Component.extend({
classNames: ['button'],
buttonText:"Save",
isLoading:false,
Expand All @@ -53,16 +52,14 @@ App.SpinButtonComponent = Ember.Component.extend({
}
}
});

```


### Discussion

I have dumbed down the sample code to only change text within the button. One may add a loading image inside the button or change the button to a div styled like a button.
The component is in charge of setting isLoading = true and the base controller performing asynchronous action decides when the 'isLoading' becomes false again.
For safety and sanity of the component, one can add a settimeout of however much time and then set 'isLoading' back to false so that the components comes to initial state no matter the result of the asynchronous call. But I would prefer it was properly handled in the parent controller.
Also note that the component does not let multiple clicks get in the way of loading status.

#### Example
<a class="jsbin-embed" href="http://emberjs.jsbin.com/EXaxEfE/14/embed?live">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script>
<!---#### Example
<a class="jsbin-embed" href="http://jsbin.com/patikodeje/7/embed?live">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script>-->
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ You want to add CSS class names to your Ember Components.

Set additional class names with the `classNames` property of subclassed components:

```js
App.AwesomeInputComponent = Ember.Component.extend({
```app/component/awesome-input.js
export default Ember.Component.extend({
classNames: ['css-framework-fancy-class']
})
});
```

```handlebars
Expand All @@ -28,8 +28,8 @@ If desired, you can apply multiple class names.
classNames: ['bold', 'italic', 'blue']
```

#### Example
<!---#### Example

<a class="jsbin-embed" href="http://emberjs.jsbin.com/ifUDExu/2/edit?js,output">JS Bin</a>
<a class="jsbin-embed" href="http://jsbin.com/gihupoqeja/2/embed?live">JS Bin</a>

See [Customizing a Component's Element](../../components/customizing-a-components-element/) for further examples.
See [Customizing a Component's Element](../../components/customizing-a-components-element/) for further examples. -->
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ classNameBindings: ['isRelated:relative'],
isRelatedBinding: "content.isRelated" // value resolves to boolean
```

#### Example
<!--- #### Example

<a class="jsbin-embed" href="http://emberjs.jsbin.com/AwAYUwe/2/edit?js,output">JS Bin</a>
<a class="jsbin-embed" href="http://jsbin.com/jogizaqepe/2/embed?live">JS Bin</a>

See [Customizing a Component's Element](../../components/customizing-a-components-element/) for further examples.
See [Customizing a Component's Element](../../components/customizing-a-components-element/) for further examples. -->
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ that the field has been focused, and add a computed property named
been focused. The component expects to get the validation result as the
`valid` property.

```javascript
App.ValidatedInputComponent = Ember.Component.extend({
```app/components/validated-input.js
export default Ember.Component.extend({
beenFocused: false,
valid: null,
hasError: function() {
Expand All @@ -31,12 +31,10 @@ And in the template of the component, put an `{{input}}` and wrap it
into a div, which would have the class of `has-error` bound to
`hasError`.

```html
<script type="text/x-handlebars" data-template-name="components/validated-input">
<div {{bindAttr class="hasError :form-group"}}>
```app/templates/components/validated-input.hbs
<div {{bindAttr class="hasError :form-group"}}>
{{input type=type value=value size=size pattern=pattern name=name placeholder=placeholder disaled=disabled maxlength=maxlength tabindex=tabindex class=input-class}}
</div>
</script>
```

The use like this:
Expand All @@ -62,6 +60,6 @@ It renders a wrapped input field. The wrapper has the `has-error` class
if `hasError` property of the component is true. It's true only when
the validation fails and the field has been focused at.

#### Example
<!---#### Example

<a class="jsbin-embed" href="http://jsbin.com/UpaXeta/3/embed?live">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script>
<a class="jsbin-embed" href="http://jsbin.com/UpaXeta/3/embed?live">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script> -->
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@ formattedAmount: function(key, value) {
}.property('amount')
```

#### Example

<a class="jsbin-embed" href="http://emberjs.jsbin.com/AqeVuZI/2/embed?live,js,output">JS Bin</a>
<!---#### Example

<a class="jsbin-embed" href="http://emberjs.jsbin.com/AqeVuZI/2/embed?live">JS Bin</a>-->
[setters]: /guides/object-model/computed-properties/
[accounting]: http://josscrowcroft.github.io/accounting.js/

Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ Let's look at a simple example. You're working on a website for your
client, and one of the requirements is to have the current date on the index page in human readable format. This is a perfect place to use a
Handlebars helper that "pretty prints" the current date:

```javascript
Ember.Handlebars.registerBoundHelper('currentDate', function() {
```app/helpers/current-date.js
export default Ember.Handlebars.makeBoundHelper(function() {
return moment().format('LL');
});
```
Expand All @@ -29,10 +29,13 @@ Today's date: {{currentDate}} // Today's date: August 30 2013

You can even enhance your code and pass in the date format to the helper:

```javascript
```app/route/application.js
Ember.Handlebars.registerBoundHelper('currentDate', function(format) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please review this section (about to push now). I set up the "makeBoundHelpers" and "registerBoundHelper" based on what was working for me in the jsbin (the ember-cli prototype).

I am assuming this means "remove the import" but not sure what exact line number this is pointing to (or the whole section?)

return moment().format(format);
});

export default Ember.Route.extend({
});
```

Now you would need to pass an additional parameter to the helper:
Expand All @@ -49,8 +52,8 @@ Define `formattedDate` computed property that depends on
`date` and `format`. Computed property in this example does
the same thing as Handlebars helpers defined above.

```javascript
App.ApplicationController = Ember.Controller.extend({
```app/controllers/application.js
export default Ember.Controller.extend({
format: "YYYYMMDD",
date: null,
formattedDate: function() {
Expand All @@ -61,7 +64,7 @@ App.ApplicationController = Ember.Controller.extend({
});
```

```html
```/app/templates/application.hbs
{{input value=date}}
{{input value=format}}
<div>{{formattedDate}}</div>
Expand All @@ -84,6 +87,6 @@ Handlebars helper with one big difference:
`formattedDate` can be consumed later without applying
date format on the date property again.

#### Example
<!---#### Example

<a class="jsbin-embed" href="http://emberjs.jsbin.com/iCaGUne/4/edit?output">JS Bin</a>
<a class="jsbin-embed" href="http://jsbin.com/nipujoneqe/1/embed?live">JS Bin</a>-->
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Subclass `Ember.TextField` and define a method marked with
`.on('didInsertElement')`. Inside this method apply `focus`
to the text field by accessing the components's jQuery `$` property:

```javascript
App.FocusInputComponent = Ember.TextField.extend({
```app/components/focus-input.js
export default Ember.TextField.extend({
becomeFocused: function() {
this.$().focus();
}.on('didInsertElement')
Expand Down Expand Up @@ -47,6 +47,6 @@ of our component.

Prototype extension can be disabled by setting the `Ember.EXTEND_PROTOTYPES` property to false.

#### Example
<!---#### Example

<a class="jsbin-embed" href="http://emberjs.jsbin.com/OlUGODo/4/edit?html,js,output">JS Bin</a>
<a class="jsbin-embed" href="http://jsbin.com/yejamevaqa/1/embed?live">JS Bin</a>-->
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ The page scroller keeps in the same position when you go from one page to anothe

Add the following mixin to the affected Routes:

```js
App.ResetScroll = Ember.Mixin.create({
```app/mixins/reset-scroll.js
export default Ember.Mixin.create({
activate: function() {
this._super();
window.scrollTo(0,0);
Expand All @@ -17,8 +17,10 @@ App.ResetScroll = Ember.Mixin.create({

Only if you need do something on the `activate` method you must call `this._super()` at the beginning:

```js
App.IndexRoute = Ember.Route.extend(App.ResetScroll, {
```app/routes/index.js
import ResetScroll from '../mixins/reset-scroll/';

export default Ember.Route.extend(ResetScroll, {
//I need to do other things with activate
activate: function() {
this._super.apply(this, arguments); // Call super at the beginning
Expand All @@ -27,6 +29,6 @@ App.IndexRoute = Ember.Route.extend(App.ResetScroll, {
});
```

#### Example
<!---#### Example

<a class="jsbin-embed" href="http://emberjs.jsbin.com/kixowati/1/embed?html,js,output">Ember Starter Kit</a><script src="http://static.jsbin.com/js/embed.js"></script>
<a class="jsbin-embed" href="http://jsbin.com/yiqijopilo/1/embed?live">Ember Starter Kit</a><script src="http://static.jsbin.com/js/embed.js"></script>-->
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ life, you can specifiy that the property is not bound by applying the `{{unbound
that is not bound will avoid adding unnecessary observers on a property.


#### Example
<!---#### Example

<a class="jsbin-embed" href="http://emberjs.jsbin.com/ayUkOWo/3/edit?output">JS Bin</a>
<a class="jsbin-embed" href="http://jsbin.com/sazomoceza/15/edit?output">JS Bin</a>-->