控制器(controller)
/ / 阅读耗时预计 3 分钟从本篇开始进入第五章控制器,controller
在Ember2.0
开始越来越精简了,职责也更加单一——处理逻辑。
下面是准备工作。
重新创建一个Ember项目,仍旧使用的是Ember CLI命令创建。
1 | ember new chapter5_controllers |
在浏览器执行项目,看到如下信息说明项目搭建成功。
Welcome to Ember。
1,控制器简介
控制器与组件非常相似,由此,在未来的新版本中很有可能组件将会完全取代控制器,很可能随着Ember版本的更新控制器将退出Ember。目前的版本中组件还不能直接通过路由访问,需要通过模板调用才能使用组件,但是未来的版本会解决这个问题,到时候controller
可能就真的从Ember退出了!
正因如此,模块化的Ember应用很少用到controller
。即便是使用了controller
也是为了处理下面的两件事情:
controller
主要是为了维持当前路由状态。一般来说,model的属性会保存到服务器,但是controller
的属性却不会保存到服务器。- 组件上的动作需要通过
controller
层转到route
层。
模板上下文的渲染是通过当前controller
的路由处理的。Ember所追随的理念是“约定优于配置”,这也就意味着如果你只需要一个controller
你就创建一个,而不是一切为了“便于工作”。
下面的例子是演示路由显示blog post
。假设模板blog-post
用于展示模型blog-post
的数据,并在这个模型包含如下属性(隐含属性id
,因为在model
中不需要手动指定id
属性):
- title
- intro
- body
- author
model
定义如下:
1 | // app/models/blog-post.js |
在route
层增加测试数据,直接返回一个model
对象。
1 | // app/routes/blog-post.js |
显示信息的模板如下:
1 | <!-- app/templates/blog-post.hbs --> |
如果你的代码没有编写错误那么也会得到如下结果:
Welcome to Ember是主模板的信息,你可以在application.hbs
中删除,但是记得不要删除{{outlet}}
,否则什么信息也不显示。
这个例子中没有显示任何特定的属性或者指定的动作(action
)。此时,控制器的model属性所扮演的角色仅仅是模型属性的pass-through
(或代理)。
注意:控制器获取的model
是从route
得到的。
下面为这个例子增加一个功能:用户可以点击标题触发显示或者隐藏post
的内容。通过一个属性isExpanded
控制,下面分别修改模板和控制器的代码。
1 | // app/controllers/blog-post.js |
在controller
中增加一个属性isExpanded
,如果你不在controller
中定义这个属性也是可以的。对于这个controller
代码的解释请看Ember.js 入门指南之十五 助手。
1 | <!-- app/templates/blog-post.hbs --> |
在模板中使用if
助手判断isExpanded
的值,如果为true
则显示body
,否则不显示。
页面加载之后结果如下,首先是不显示body
内容,点击按钮“Show body”则显示内容,并且按钮变为“hide body”。然后在点击这个按钮则不显示body
内容。
到此controller
的职责你应该大致了解了,其主要的作用是逻辑的判断、处理,比如这里例子中判断body
内容的显示与否,其实你也可以把controller
类中的处理代码放在route
类中也可以实现这个效果,但是要作为model
的属性返回(把isExpanded
当做model
的属性处理),请读者自己动手试试,但是把逻辑放到route
又会使得route
变得“不专一”了,route
的主要职责是初始化数据的。我想这也是Ember还留着controller
的原因之一吧!!
博文完整代码放在[Github](https://github.com/ubuntuvim/my_emberjs_code)(博文经过多次修改,博文上的代码与github代码可能有出入,不过影响不大!),如果你觉得博文对你有点用,请在github项目上给我点个`star`吧。您的肯定对我来说是最大的动力!!