一、概述

应用程序中,templates被models支持。但是templates是如何知道它们应该显示哪个model呢?

例如,你有一个photos模板,它是如何知道它该呈现哪个model呢?

这就是Ember.Route工作的一部分。你可以通过定义一个和template同名的route来告诉模板呈现哪个模型,并且实现model hook

例如,为photos模板提供一些model属性,我们定义一个route:photos对象:

app/routes/photos.js

export default Ember.Route.extend({
model() {
return [{
title: "Tomster",
url: "http://emberjs.com/images/about/ember-productivity-sm.png"
}, {
title: "Eiffel Tower",
url: "http://emberjs.com/images/about/ember-structure-sm.png"
}];
}
});

二、Asynchronously Loading Models(异步加载模型)

1. 在上面的示例中,模型数据是从model hook被同步返回的。这意味着数据可以立即使用,你的app不需要等待它加载,在这种情况下,因为我们马上返回数组的硬编码数据。

2. 当然,这不总是现实的。通常,数据同步将不可用,但是相反必须通过网络异步加载。例如,我们可以通过一个服务器上可用JSON API来检索照片列表。

3. 在异步数据可用的情况下,你可以从model hook仅仅返回一个promise,在呈现模板前Ember会一直等待,直到这个promise被解决。

3. 如果你对promises不熟悉,它的基本思路是,它们是代表最终值的对象。例如,如果你使用jQuery的getJSON()方法,它将会为最终通过网络返回的JSON返回一个promise。Ember使用这个promise对象去了解什么时候它有足够的数据去渲染。

4. 看一个例子。这是一个路由,它加载GitHub上最近发送到Ember.js的pull request:

app/routes/pull-requests.js

export default Ember.Route.extend({
model() {
return Ember.$.getJSON('https://api.github.com/repos/emberjs/ember.js/pulls');
}
});
  • 虽然这个例子看起来是同步的,因此很容易阅读和推理,它实际上完全是异步的。
  • 因为jQuery的getJSON()方法返回一个promise。Ember检测到从一个model hook中返回了一个promise,并等待,直到这个promise解决呈现pullRequests模板。

5. 因为Ember支持promises,它可以和任何使用它们作为它的公共API的一部分的存在的库一起工作。你还可以基于promises使用很多便利使代码变得更好。

6. 例如,设想如果你需要修改上面的例子,以便模板仅仅显示最近三个pull requests。在数据传递到模板之前,我们可以依赖promise链去修改从JSON请求中返回的数据。

app/routes/pull-requests.js

export default Ember.Route.extend({
model() {
var url = 'https://api.github.com/repos/emberjs/ember.js/pulls';
return Ember.$.getJSON(url).then(function(data) {
return data.splice(0, 3);
});
}
});

三、Setting Up Controllers With The Model

所以从model hook中返回的值实际上发生了什么?

1. 默认的,从model hook返回的值将被指派给model属性相关的controller。例如,如果你的route:posts从它的model hook返回一个对象,这个对象将被设置为controller:postsmodel属性。

(这一点,私底下,模板是如何知道去加载哪一个model:它们需找它们相关的controllermodel属性。例如,photos模板将会呈现,无论controller:photosmodel被设置为什么。)

2. 默认行为可以被改变。注意,如果你重写默认行为但是不给controller设置model属性的话,你的模板不会呈现任何数据。

四、Dynamcic Models

1. 一些路由通常展现同样的model。例如,在应用程序中路由/photos通常展现相同的photos列表。如果用户离开这个route并且稍后返回,model不会改变。

2. 然而,你会有一个路由,它的model会根据用户交互改变。例如,假设一个photo viewer app。/photos路由将会用photos列表作为model渲染photos模板,这个从来不会变。但是当用户点击一个指定的照片,我们希望用photo模板展示该模型。如果用户返回并且点击一个不同的照片,我们希望再一次展示photo模板,这次是用一个不同的model。

3. 在这样的情况下,在URL中不仅包括要显示的模板而且还包括model,这很重要。

4. 在Ember中,这是通过使用动态字段定义路由来实现的。

5. 一个动态字段是URL的一部分,它使用当前model的id来填充。动态字段通常以":"开始。

我们的photo例子定义的photo路由:

Router.map(function() {
this.route('photo', { path: '/photos/:photo_id' });
});
  • 在例子中,photo路由有一个动态字段:photo_id。当用户进入photo路由去展现一个指定的model(通常通过{{#link-to}})时,模型的id将会被自动放入URL中。

6. 例如,如果你转换到photo路由,使用一个id为47的model,用户浏览器中的URL将会被更新为:/photos/47

7. 如果用户通过包含动态字段的URL直接访问app会发生什么?例如,他们可能会UI重新加载页面,或者向朋友发送链接。在这一点上, 因为我们是从暂存器启动app的,实际上JS model对象已经丢失了,我们有的仅仅是从URL上得到的ID。

8. 幸运的是,Ember将会从URL上提取任何动态字段并且将它们作为一个hash传递到model hook,作为它的第一个参数。

app/router.js

Router.map(function() {
this.route('photo', { path: '/photos/:photo_id' });
}); 

app/routes/photo.js

export default Ember.Route.extend({
model(params) {
return Ember.$.getJSON('/photos/'+params.photo_id);
}
});

在model hook中对于有动态字段的路由,你的工作是把ID传入一个model,它可以被路由的模板渲染。在上面的例子中,我们用照片的ID构造一个URL用于该照片的JSON表示。一旦我们拥有了URL,我们使用jQuery来为JSON模型数据返回一个promise。

9. 注意,当直接通过URL进入路由时,一个有动态字段的路由将会仅仅调用它的modle hook。如果route是通过跳转(例如link-to)进入的,模型上下文已经存在了并且钩子方法不会执行。没有动态字段的路由仍然执行model hook。

五、Refreshing Your Model

如果你的模型数据更新频繁,你可能想要定期刷新:

controller可以传递一个action给route。在上面的例子中,IndexController暴露一个getLatest action,它传递一个action调用invalidateModel。调用路由的refresh方法将会前置Ember再一次执行model hook。

六、Ember Data

许多Ember开发者使用一个model库来更容易的查找和存储记录,这比手动调用Ajax更简单。特别的,使用一个model库允许你缓存已经加载的记录,显著提高应用程序的性能。

一个流行的基于Ember的model库是Ember Data。

4.4 Routing -- Specifying A Route's Model的更多相关文章

  1. Akka(32): Http:High-Level-Api,Route exception handling

    Akka-http routing DSL在Route运算中抛出的异常是由内向外浮出的:当内层Route未能捕获异常时,外一层Route会接着尝试捕捉,依次向外扩展.Akka-http提供了Excep ...

  2. A Quick Introduction to Linux Policy Routing

    A Quick Introduction to Linux Policy Routing 29 May 2013 In this post, I’m going to introduce you to ...

  3. Orchard源码分析(7.1):Routing(路由)相关

    概述 关于ASP.NET MVC中路由有两个基本核心作用,一是通过Http请求中的Url参数等信息获取路由数据(RouteData),路由数据包含了area.controller.action的名称等 ...

  4. laravel route路由,视图和response和filter

    Laravel充分利用PHP 5.3的特性,使路由变得简单并富于表达性.这使得从构建API到完整的web应用都变得尽可能容易.路由的实现代码在 application/routes.php 文件. 和 ...

  5. Emberjs View and Route

    index.html <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset=& ...

  6. dotnet core 开发体验之Routing

    开始 回顾上一篇文章:dotnet core开发体验之开始MVC 里面体验了一把mvc,然后我们知道了aspnet mvc是靠Routing来驱动起来的,所以感觉需要研究一下Routing是什么鬼. ...

  7. ASP.NET Routing

    ASP.NET Routing Other Versions   ASP.NET routing enables you to use URLs that do not have to map to ...

  8. 关于Linux路由表的route命令(转)

    查看 Linux 内核路由表 使用下面的 route 命令可以查看 Linux 内核路由表. # route Destination  Gateway      Genmask          Fl ...

  9. ASP.NET Web API中的Routing(路由)

    [译]Routing in ASP.NET Web API 单击此处查看原文 本文阐述了ASP.NET Web API是如何将HTTP requests路由到controllers的. 如果你对ASP ...

随机推荐

  1. java中定义一个CloneUtil 工具类

    其实所有的java对象都可以具备克隆能力,只是因为在基础类Object中被设定成了一个保留方法(protected),要想真正拥有克隆的能力, 就需要实现Cloneable接口,重写clone方法.通 ...

  2. VS2015编译OpenSSL1.0.2源码

    更多详细信息http://blog.csdn.net/YAOJINGKAO/article/details/53041165?locationNum=10&fps=1 1.下载安装编译必须的A ...

  3. java运行显示“找不到或无法加载主类”的解决办法(linux)

    要是配置文件的路径问题.打开终端,输入vi ~/.bashrc添加如下代码即可. # set Java environmentJAVA_HOME=/usr/local/java/jdk1.8.0PAT ...

  4. FTP新建文件夹访问

    今天在远程服务器上添加了文件夹,本来还想着FTP打开看看,结果竟然发现没有这个文件夹访问 想了一下,感觉应该是FTP访问的文件设置,只有FTP设置了的文件夹才能有显示

  5. 17,UC(06)

    /*  达内学习 UC day06 2013-10-10 */ 回忆过去:  系统调用 - UNIX操作系统提供的一些列函数皆苦,用于访问内核空间,遵循posix规范  文件操作:open()\rea ...

  6. Android 菜单动态变化【添加或去除】

    <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android: ...

  7. python小项目练习之转换像素图片为字符图

    实例来源实验楼网站,没事可以多逛逛,在此多谢实验楼的无私分享 from PIL import Image import argparse """ description: ...

  8. Elasticsearch配置参数介绍

    Elasticsearch的config文件夹里面有两个配置文件:elasticsearch.yml和logging.yml.第一个是es的基本配置文件,第二个是日志配置文件,es也是使用log4j来 ...

  9. 微信小游戏 查看egret的小游戏支持库版本

    在开发者工具 console输入egret.wxgame

  10. javascript飞机大战-----009游戏结束

    /* 游戏引擎 */ var Engine = { //刚开始的游戏状态 gameStatus:false, //所以敌机 enemy:{}, //子弹 bullet:{}, //得分 scroe:0 ...