Ember命名规则

目录 [−]

  1. Application
  2. 简单路由
  3. 动态片段 Dynamic Segment
  4. 缺省的 Route, Controller 和 Template
  5. 嵌套
  6. Index路由
  7. Model
  8. 视图 View
  9. 组件 Component
  10. Serializer
  11. Adapter

Ember.js定义了命名的规则, 相应的MVC javascript的名字应当遵循此规则, 并且依照此规则, 有些文件就可以省略。这篇文章整理了Ember的命名的约定规则, 有些官方文档给出了说明, 有些散落在其它文档以上网上的问答中。 有些甚至没有文档记录,Ember.js的文档还是很匮乏的。这篇文章很好的对命名约定(规则)做了一个总结。

Application

Ember应用启动时, 它会寻找一下三个对象。

  • App.ApplicationRoute
  • App.ApplicationController
  • application 模版

application将作为应用的主模版。 你可以在此模版设计你网站的整体布局。 比如顶部菜单栏, 底部版权声明等。
App.ApplicationController作为此模版的controller。
渲染application 模版前会首先调用App.ApplicationRoutehook方法,如model,renderTemplate, setupController等。

简单路由

首先配置一个简单路由:

1
2
3
App.Router.map(function() {
this.route('favorites');
});

当你访问/favorites时,Ember将查找以下对象:

  • App.FavoritesRoute
  • App.FavoritesController
  • favorites

Ember渲染favorites 模版并替换application模版的

动态片段 Dynamic Segment

动态片段是URL包含参数。 看一个例子。

1
2
3
App.Router.map(function() {
this.resource('post', { path: '/posts/:post_id' });
});

route名字是post,Ember查找以下对象:

  • App.PostRoute
  • App.PostController
  • post 模版

路由可以在hook方法中处理参数。

1
2
3
4
5
6
7
8
9
App.PostRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('post', params.post_id);
},
serialize: function(post) {
return { post_id: post.get('id') };
}
});

约定 : 如果参数以_id为后缀, 那么上面的model方法可以省略,Ember可以使用缺省的 model方法。
如果不实现serialize, 默认使用id属性的值作为参数的值。

缺省的 Route, Controller 和 Template

以上面的配置为例,

  • 如果不指定App.PostRoute, Ember依然使用App.PostController渲染post 模版
  • 如果不指定App.PostController,Ember会根据model hook方法的返回值自动创建一个。 如果model返回数组,则创建ArrayController, 否则创建ObjectController
  • 如果没有post模版,Ember不会渲染任何东西(Empty)

嵌套

看一个嵌套的例子:

1
2
3
4
5
6
App.Router.map(function() {
this.resource('posts', function() { // the `posts` route
this.route('favorites'); // the `posts.favorites` route
this.resource('post'); // the `post` route
});
});

2014 8月23日 发布的Ember 1.7.0 已经支持route嵌套, 不仅仅是reourse
一个resource将作为它的route, controller,和template的名字的开始部分。 尽管post resource嵌套在posts之中,它的路由依然是App.PostRoute,controller还是App.PostController,模版是post
如果在resource嵌套一个route如favorites,路由的名字会加上resource的名字, 并以.分隔。

Route NameControllerRouteTemplate
postsPostsControllerPostsRouteposts
posts.favoritesPostsFavoritesControllerPostsFavoritesRouteposts/favorites
postPostControllerPostRoutepost

一般resource使用名词。route使用形容词或者动词。

你可以使用浏览器插件Ember Inspector去查看所有的约定的对象。

Index路由

对于每一级的嵌套,Ember会自动为"/"生成一个index路由。

1
2
3
App.Router.map(function() {
this.route('favorites');
});

等价于

1
2
3
4
App.Router.map(function() {
this.route('index', { path: '/' });
this.route('favorites');
});

对应的对象为

  • App.IndexRoute
  • App.IndexController
  • index 模版

index模版会被渲染并替换application模版的。

1
2
3
4
5
App.Router.map(function() {
this.resource('posts', function() {
this.route('favorites');
});
});

等价

1
2
3
4
5
6
7
App.Router.map(function() {
this.route('index', { path: '/' });
this.resource('posts', function() {
this.route('index', { path: '/' });
this.route('favorites');
});
});

Model

一般, 我们会将model的名字命名成和resource一样。
如resource的名字是'post',model的名字为post.

视图 View

由于Handlebars 模版引擎非常强大, view在ember开发中重要性不像其它框架那么大了。
视图的名字约定和Route一样,对于上面的post 路由, 以下缺省的命名。
route名字是post,Ember查找以下对象:

  • App.PostRoute
  • App.PostController
  • post 模版
  • App.PostView

如果你不想使用默认的约定命名, 你可以显示指定view和template:

1
2
3
4
5
6
7
8
9
App.PostView = Ember.View.create({
templateName: 'myTemplate'
});
App.SomeRoute = Ember.Route.extend({
renderTemplates: function(controller,model){
this.render("post"); //view name
}
});

组件 Component

如果你想增加一个组件, 你需要将它的模版放到components/下。 比如, 你想增加一个组件0,它的模版为components/blog-post
组件的名字必须包含一个破折号- blog-post是一个合法的名字但是post不是。
如果组件名为blog-post, 那么组件的类名应该是App.BlogPostComponent.

Serializer

使用Ember data时, 当record被传入或者传出时, Serializer用来序列化/反序列化一组record。
正常情况下, Ember使用RESTSerializer实现normalize方法。更多的方法请参考这里
应用程序的 DS.Adapter负责创建serializer 并在处理数据时调用相应的方法。
如果你的model定义如下:

1
2
3
App.Person = DS.Model.extend({
firstName: DS.attr('string')
});

但是你的API是个遗留系统, 字段名为FIRST_NAME, 你可以定义serializer进行处理:

1
2
3
keyForAttributeName: function(type, name) {
return name.underscore.toUpperCase();
}

对于serializer名字的定义, 一般定义成model名+ Serializer, 如App.PostSerializer
App.ApplicationSerializer用来定义全局的序列化器。

Adapter

Adapter 接收来自store的请求并把它们翻译成合适的持久层的动作。 持久层一般是一个HTTP API, 开发过程中也可能是浏览器的本地存储。
App.ApplicationAdapter = DS.RESTAdapter.extend({..., serializer: App.ApplicationSerializer.create(),...});
用来定义全局的Adaptor。

如果model需要特别的adapter,可以定义特别的adapter, 名字为model name +Adapter, 如App.PostAdapter

默认的动作规则为:

ActionHTTP VerbURL
FindGET/people/123
Find AllGET/people
UpdatePUT/people/123
CreatePOST/people
DeleteDELETE/people/123

你还可以定义host和namespace来定义特定的url。