文章目录
  1. 1. 新版本的框架
  2. 2. Object对象
  3. 3. Routing
  4. 4. Models
  5. 5. Services
  6. 6. Components

从Ember 2.x开始,它的模型在概念上比以前清晰明了的多,你不用再纠结于templaterouteviewcontrollermodelcomponent等概念。

新版本的框架

在Ember 2.x的版本中我们需要注意其中的五个概念:object modelroutingmodelsservicescomponents

Ember的routing层会根据URL来指定一个model来处理对应的component用于展示和交互,其中也许会用到service来获取models
如下是一个详细的示例图:

处理流程如下:

  • Router解析URL/items/2,并且委派给对应的route:ItemRoute来处理,同时携带参数:item_id=2
  • ItemRoute调用它的model()方法,这个方法会通过service来获取数据并返回一个model对象
  • renderComponent()方法会渲染对应的一个component:ItemDisplayComponent
  • ItemDisplayComponent主要用来处理渲染页面,用户交互等逻辑处理

这就是Ember新版本的一个基本处理流程。下面我们探讨下它的五个基本概念。

Object对象

Javascript的原生object对象缺乏observe的功能,Ember引入了Ember.Object,它在原生object对象的基础上增加了observers,计算属性,继承,mixins和其他有用的功能。
这也是为什么我们需要使用object.set('id', "value")而不是object.id = "value"

1
2
3
4
5
6
7
fullName: Ember.computed('firstName', 'lastName', function() {
return this.get('firstName') + " " + this.get('lastName');
});
fullNameDidChange: Ember.observer('fullName', function() {
this.send('fullNameChanged');
});

自动监控对象的改变并更新对应的展现给我们的应用带来了极大的便利。Ember中的大多数对象,包括routes,Ember data models,services和components都继承了Ember.Object

Routing

Ember是基于URL驱动的框架,如下:

1
2
3
4
// app/router.js
...
this.route('item', { path: '/items/:item_id' });
...

需要注意的是,在Ember中,规范比配置更重要。当我们无论何时指定一个item route时,Ember就会默认指向ItemRoute这个类,且它的路径为app/routes/item.js,如果没有找到这个类,它就会自动给我们创建一个。
ItemRoute会调用model()方法:

1
2
3
4
5
6
7
8
9
10
// app/routes/item.js
export default Ember.Route.extend({
model(params) {
return {
id: params.item_id,
text: "This is item " + params.item_id
}
}
});

一旦model()有返回后,我们的renderComponent()就会用这个model数据来调用ItemDisplayComponent
routes不仅仅是把数据传下去,同时它也接受actions,actions来自于components或其他的routes,如:

1
2
3
4
5
6
7
8
9
10
export default Ember.Route.extend({
actions: {
remove(item) {
item.remove().then(() => {
this.transitionTo('index');
});
}
}
...
});

我们更新下流程图来反应remove action:

这个图也反应了Ember的data down, actions up设计思想。

Models

上面model中只返回了原始的javascrip对象数据,实际上它还可以用来处理更复杂的情形。

model可以通过$.getJSON()来获取数据。

1
2
3
4
5
export default Ember.Route.extend({
model() {
return $.getJSON('/items.json');
}
});

这是一个异步的请求,并且返回Promise对象。

1
2
3
4
5
export default Ember.Route.extend({
model(params) {
return this.store.findRecord('item', params.item_id);
}
});

上面的请求会返回一个DS.Model实例,所有的Ember Data models都继承于它。

Services

上面我们调用了this.store,但route是如何获取store的呢?实际上Ember是通过它的Injection API将它的store service注入到应用中的所有routes中。
我们也可以创建自己的service,然后通过注入的方式来调用:

1
2
3
4
export default Ember.Route.extend({
crypto: Ember.inject.service()
...
})

Ember会自动的查找app/services/crypto.js文件,并且可以通过this.get('crypto')来使用这个service。

Components

Components分为两部分:模版和逻辑处理文件。当前是通过如NaN方式来加载component,后面我们会使用<my-component>方式来加载。

1
2
3
4
5
6
7
// app/components/item-display.js
export default Ember.Component.extend({
isModelTwo: Ember.computed('model.id', function() {
return this.get('model.id') == 2;
})
});

模版:

1
2
3
4
5
6
7
{{!-- app/templates/components/item-display.hbs --}}
<h1>{{ model.text }}</h1>
{{#if isModelTwo}}
<p><strong>OMG MODEL TWO!</strong></p>
{{/if}}

Components中可以嵌套包含其他的components:

1
2
3
4
5
6
7
<h1>{{i18n-display text=model.text}}</h1>
{{#if isModelTwo}}
<p><strong>OMG MODEL TWO!</strong></p>
{{/if}}
{{ad-items language="en" seed=model}}

文章目录
  1. 1. 新版本的框架
  2. 2. Object对象
  3. 3. Routing
  4. 4. Models
  5. 5. Services
  6. 6. Components