Skip to content

Commit

Permalink
Keep it up-to-date
Browse files Browse the repository at this point in the history
  • Loading branch information
towerhe committed Dec 5, 2013
1 parent 5ad0da2 commit f8da834
Show file tree
Hide file tree
Showing 34 changed files with 421 additions and 181 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ gem "rack"
gem "listen"
gem "builder"

group :development do
group :development, :test do
gem "pry"
end

Expand Down
18 changes: 13 additions & 5 deletions lib/toc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,19 @@ def next_chapter_link(scope = :guides)
}
elsif whats_next = next_guide
next_chapter = whats_next[1][0]
%Q{
<a class="next-guide" href="/#{scope}/#{next_chapter.url}">
#{current_section[0]}结束 下一章: #{whats_next[0]} - #{next_chapter.title} \u2192
</a>
}
if section_slug == 'index.html'
%Q{
<a class="next-guide" href="/guides/#{next_chapter.url}">
#{next_chapter.title} \u2192
</a>
}
else
%Q{
<a class="next-guide" href="/guides/#{next_chapter.url}">
本章#{current_section[0]}完毕。下一章: #{whats_next[0]} - #{next_chapter.title} \u2192
</a>
}
end
else
''
end
Expand Down
12 changes: 9 additions & 3 deletions source/bilingual_guides/concepts/naming-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,15 @@ the controller.

If your app provides an `App.ApplicationRoute`, Ember.js will invoke
[the][1] [router's][2] [hooks][3] first, before rendering the
`application` template.

如果你的应用提供了`App.ApplicationRoute`,`Ember.js`将在渲染`application`模板前先调用[][1][路由][2][钩子程序][3]
`application` template. Hooks are implemented as methods and provide
you access points within an Ember objects lifecycle to intercept and
execute code to modify the default behavior at these points to meet
your needs. Ember provides several hooks for you to utilize for
various purposes (e.g. `model`, `setupController`, etc). In the example below
`App.ApplicationRoute`, which is a `Ember.Route` object, implements
the `setupController` hook.

如果你的应用提供了`App.ApplicationRoute`,`Ember.js`将在渲染`application`模板前先调用[][1][路由][2][钩子程序][3]。钩子都作为方法来实现,提供了对Ember对象生命周期的访问点,可以拦截和执行代码来改变这些点的缺省行为,以符合实际需求。Ember为各种需求提供了一系列钩子(例如:`model``setupController`等等)。在下面的实例中,`App.ApplicationRoute`是一个实现了`setupController`钩子的`Ember.Route`对象。

[1]: /guides/routing/specifying-a-routes-model
[2]: /guides/routing/setting-up-a-controller
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ fullNameDidChange: function() {

// Instead, do this:
//你需要这样做:
fullNameDidChange: Ember.observer(function() {
fullNameDidChange: Ember.observer('fullName', function() {
console.log("Full name changed");
}, 'fullName')
})
```
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ We will use [MomentJs](http://momentjs.com) for formatting dates.
这里将使用[Moment.js](http://momentjs.com)来做日期格式化。

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 readble format. This is a perfect place to use a
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:

下面来看一个简单的例子。假设正在给客户开发一个网站,其中的一个需求是在首页显示一个易读的当前时间。这是一个非常适合使用Handlebars助手来实现的应用场景:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
## Problem

You want to display dates in relative form.

## Solution

[Moment.js](http://momentjs.com) will be used for formatting the dates.

Start by creating a new view, which would just render the result of
`moment().fromNow()` and register a helper for it.

```javascript
App.FromNowView = Ember.View.extend({
tagName: 'time',
template: Ember.Handlebars.compile('{{view.fromNow}}'),

fromNow: function() {
return moment(this.get('value')).fromNow();
}.property('value')
});

Ember.Handlebars.helper('fromNow', App.FromNowView);
```

Relative dates, however, need to be updated periodically, so we'll
trigger a view re-render every second.

```javascript
App.FromNowView = Ember.View.extend({
// ...
nextTick: null,

didInsertElement: function() {
this.tick();
},

tick: function() {
var nextTick = Ember.run.later(this, function() {
this.notifyPropertyChange('value');
this.tick();
}, 1000);
this.set('nextTick', nextTick);
},

willDestroyElement: function() {
Ember.run.cancel(this.get('nextTick'));
}
});
```

Now the template can be like this:

```html
created {{fromNow value=createdAt}}
```

## Discussion

#### Example

<a class="jsbin-embed" href="http://jsbin.com/uLETuPe/1/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 @@ -24,6 +24,14 @@ App.FocusInputComponent = Ember.TextField.extend({
});
```

For the component's template:

组件模板:

```handlebars
Focus Input component!
```

```handlebars
{{focus-input}}
```
Expand Down
133 changes: 60 additions & 73 deletions source/bilingual_guides/models/finding-records.md
Original file line number Diff line number Diff line change
@@ -1,62 +1,81 @@
`store.find()` allows you to find all records, single records, and query for records.
The first argument to `store.find()` is always the type of record in question, e.g. `post`. The second
argument is optional and can either be a plain object of search options or an id. Below are some examples:
The Ember Data store provides a simple interface for finding records of
a single type through the `store` object's `find` method. Internally, the
`store` uses `find`, `findAll`, and `findQuery` based on the supplied
arguments. The first argument to `store.find()` is always the record type. The
optional second argument determines if a request is made for all records, a single
record, or a query.

`store.find()`用于查询所有的记录,包括单一记录,或基于条件查询的记录。方法的第一个参数是需要查询的记录的类型,例如:`post`,第二个参数是可选参数,可以是一个用作查询条件的对象,也可以只是一个记录的ID。下面给出一些具体的例子:
Ember Data仓库提供了一个非常简单的查询一类记录的接口,该接口就是`store`对象的`find`方法。在内部,`store`根据传入的参数使用`find``findAll``findQuery`完成查询。`store.find()`的第一个参数是记录的类型,第二个可选参数确定查询是获取所有记录,还是一条记录,还是特定的记录。

### Finding All Records of a Type

### 查询一个类型的所有记录

```js
```javascript
var posts = this.store.find('post');
```

This will return an instance of `DS.RecordArray`. As with records, the
record array will start in a loading state with a `length` of `0`.
When the server responds with results, any references to the record array
will update automatically.
To get a list of records already loaded into the store, without making
another network request, use `all` instead.

这里将返回一个`DS.RecordArray`对象。跟记录一样,记录数组对象一开始也是正在加载的状态,其`length``0`。当服务器返回结果时,所有引用了记录数组对象的地方都会自动更新
如果希望获取已经加载到仓库中的记录的列表,而不希望通过一个网络请求去获取,可以使用`all`方法

**Note**: `DS.RecordArray` is not a JavaScript array, it is an object that
implements `Ember.Enumerable`. If you want to, for example, retrieve
records by index, you must use the `objectAt(index)` method. Since the
object is not a JavaScript array, using the `[]` notation will not work.
For more information, see [Ember.Enumerable][1] and [Ember.Array][2].
```javascript
var posts = this.store.all('post'); // => no network request
```

`find` returns a `DS.PromiseArray` that fulfills to a `DS.RecordArray`
and `all` directly returns a `DS.RecordArray`.

**注意**`DS.RecordArray`不是一个Javascript的数组,它是一个实现了`Ember.Enumerable`的对象。如果希望通过索引来获取记录,那么需要使用`objectAt(index)`方法来实现。由于记录数组对象不是一个Javascript数组,因此不能是`[]`来获取。更多的信息请参看[Ember.Enumerable][1][Ember.Array][2]
`find`会返回一个将使用`DS.RecordArray`来履行的`DS.PromiseArray`,而`all`直接返回`DS.RecordArray`

To get a list of records already loaded into the store, without firing
another network request, use `store.all('post')` instead.
It's important to note that `DS.RecordArray` is not a JavaScript array.
It is an object that implements [`Ember.Enumerable`][1]. This is
important because, for example, if you want to retrieve records by index, the
`[]` notation will not work--you'll have to use `objectAt(index)` instead.

获取已经加载到仓库中的记录,而不触发一个新的网络请求,可以使用`store.all('post')`方法
需要重点注意的一点是`DS.RecordArray`不是一个Javascript数组。它是一个实现了[`Ember.Enumerable`][1]的对象。这一点非常重要,因为例如希望通过索引获取记录,那么`[]`将无法工作,需要使用`objectAt(index)`来获取

[1]: http://emberjs.com/api/classes/Ember.Enumerable.html
[2]: http://emberjs.com/api/classes/Ember.Array.html

### Finding a Single Record

### 查询一个记录

You can retrieve a record by passing its model and unique ID to the `find()`
method. The ID can be either a string or a number. This will return a promise that
fulfills with the requested record:
If you provide an number or string as the second argument to
`store.find()`, Ember Data will attempt to retrieve a record of that with that ID.
This will return a promise that fulfills with the requested record:

调用`find()`方法时,指定记录模型的名称和记录唯一的ID就可以获取对应的这个记录。ID可以是字符串或者数字。`find()`方法会返回一个会使用被请求的对象来履行的承诺:
如果调用`store.find()`方法时,第二个参数是一个数字或者字符串,Ember Data将尝试获取对应ID的记录。`find()`方法将返回一个用请求的记录来履行的承诺。

```js
this.store.find('post', 1).then(function(post) {
post.set('title', "My Dark Twisted Fantasy");
});
```javascript
var aSinglePost = this.store.find('post', 1); // => GET /posts/1
```

### Querying For Records

### 查询记录

If you provide a plain object as the second argument to `find`, Ember
Data will make a `GET` request with the object serialized as query params. This
method returns `DS.PromiseArray` in the same way as `find` with no second argument.

如果传递给`find`方法的第二个参数是一个对象,Ember Data会发送一个使用该对象来序列化出来的查询参数的`GET`请求。这是方法返回与不加第二个参数时候一样的`DS.PromiseArray`

For example, we could search for all `person` models who have the name of
`Peter`:

例如,可以查询名为`Peter``person`模型的所有记录:

```javascript
var peters = this.store.find('person', { name: "Peter" }); // => GET to /persons?name='Peter'
```

#### Integrating with the Route's Model Hook

#### 与路由的模型钩子集成

As discussed in [Specifying a Route's
Model](/guides/routing/specifying-a-routes-model), routes are
As discussed in [Specifying a Route's Model](/guides/routing/specifying-a-routes-model), routes are
responsible for telling their template which model to render.

如同在[指定路由的模型](/guides/routing/specifying-a-routes-model)一节中讨论的一样,路由是负责告诉模板将渲染哪个模型。
Expand All @@ -70,59 +89,27 @@ template.

This makes it easy to write apps with asynchronous data using Ember
Data. Just return the requested record from the `model` hook, and let
Ember deal with figuring out whether a network request is needed or not:
Ember deal with figuring out whether a network request is needed or
not.

这使得使用Ember
Data的异步数据来编写应用变得容易。只需要通过`model`钩子返回请求的记录,交给Ember来处理是否需要一个网络请求
Data的异步数据来编写应用变得容易。只需要通过`model`钩子返回请求的记录,交给Ember来处理是否需要一个网络请求

```js
```javascript
App.Router.map(function() {
this.resource('posts');
this.resource('post', { path: ':post_id' });
});

App.PostsRoute = Ember.Route.extend({
model: function() {
return this.store.find('post');
}
});

App.PostRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('post', params.post_id);
}
});
```

In fact, this pattern is so common, the above `model` hook is the
default implementation for routes with a dynamic segment. If you're
using Ember Data, you only need to override the `model` hook if you need
to return a model different from the record with the provided ID.

由于上述的场景非常常用,上面的`model`钩子是具有动态端的路由的一个缺省实现。如果使用Ember Data,且希望使用一个不是与提供的ID对应的模型时,可以重现`model`钩子来实现。

### Querying For Records

### 查询记录

You can query the server by calling the store's `find()` method and
passing a hash of search options. This method returns a promise that
fulfills with an array of the search results.

通过传递一个哈希值作为`find()`方法的第二个参数,就能实现发起一个到服务器端的查询请求。该方法返回一个将使用返回的查询结果数组来履行的承诺。

For example, we could search for all `person` models who have the name of
`Peter`:

例如,可以查询名为`Peter``person`模型的所有记录:

```js
this.store.find('person', { name: "Peter" }).then(function(people) {
console.log("Found " + people.get('length') + " people named Peter.");
});
```

The hash of search options that you pass to `find()` is opaque to Ember
Data. By default, these options will be sent to your server as the body
of an HTTP `GET` request.

传递给`find()`方法的查询参数对于Ember
Data是不透明的。默认情况下,这些参数将作为HTTP的`GET`请求的`body`来发送到服务器端。

**Using this feature requires that your server knows how to interpret
query responses.**

**使用查询特性需要服务器端能够正确解析查询参数。**
18 changes: 12 additions & 6 deletions source/bilingual_guides/models/the-fixture-adapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ Using the fixture adapter entails three very simple setup steps:

Simply attach it to your instance of `Ember.Store`:

```
```javascript
var App = Ember.Application.create();
App.Store = DS.Store.extend({
revision: 13,
adapter: DS.FixtureAdapter.create()
adapter: DS.FixtureAdapter
});
```

Expand All @@ -31,7 +31,7 @@ You should refer to [Defining a Model][1] for a more in-depth guide on using
Ember Data Models, but for the purposes of demonstration we'll use an example
modeling people who document Ember.js.

```
```javascript
App.Documenter = DS.Model.extend({
firstName: DS.attr( 'string' ),
lastName: DS.attr( 'string' )
Expand All @@ -43,7 +43,7 @@ App.Documenter = DS.Model.extend({
Attaching fixtures couldn't be simpler. Just attach a collection of plain
JavaScript objects to your Model's class under the `FIXTURES` property:

```
```javascript
App.Documenter.FIXTURES = [
{ id: 1, firstName: 'Trek', lastName: 'Glowacki' },
{ id: 2, firstName: 'Tom' , lastName: 'Dale' }
Expand All @@ -53,8 +53,14 @@ App.Documenter.FIXTURES = [
That's it! You can now use all of methods for [Finding Models][2] in your
application. For example:

```
App.Documenter.find(1); // returns the record representing Trek Glowacki
```javascript
App.DocumenterRoute = Ember.Route.extend({
model: function() {
var store = this.get('store');
return store.find('documenter', 1); // returns a promise that will resolve
// with the record representing Trek Glowacki
}
});
```

#### Naming Conventions
Expand Down
4 changes: 2 additions & 2 deletions source/bilingual_guides/object-model/observers.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,9 @@ are using Ember without prototype extensions:

```javascript
Person.reopen({
fullNameChanged: Ember.observer(function() {
fullNameChanged: Ember.observer('fullName', function() {
// 这是内联式版本的 .addObserver
}, 'fullName')
})
});
```

Expand Down
Loading

0 comments on commit f8da834

Please sign in to comment.