一、概述

应用程序中,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. POJ 1946 Cow Cycling(抽象背包, 多阶段DP)

    Description The cow bicycling team consists of N (1 <= N <= 20) cyclists. They wish to determi ...

  2. swift开发之 -- 自动轮播图(UIScrollView+UIPageControl+Timer)

    比较简单,原理就不说了,这里只做记录: 代码如下: 1,准备 var pageControl:UIPageControl? var myscrollView:UIScrollView? var myT ...

  3. Android 程序员必须知道的 53 个知识点

    1. android 单实例运行方法 我们都知道 Android 平台没有任务管理器,而内部 App 维护者一个 Activity history stack 来实现窗口显示和销毁,对于常规从快捷方式 ...

  4. zookeeper-端口说明

    一.zookeeper有三个端口(可以修改) 1.2181 2.3888 3.2888 二.3个端口的作用 1.2181:对cline端提供服务 2.3888:选举leader使用 3.2888:集群 ...

  5. 设计模式之模板方法模式(Java实现)

    "那个,上次由于我老婆要给我做饭,所以就没有说完就走掉了...这个那个".这次和以前一样,先来开场福利(工厂方法模式已被作者踹下场).由美女抽象工厂介绍一下适用场景~大家欢迎 抽象 ...

  6. Linux进程数据结构详解

    1.Linux的进程简介: 支持多线程的操作系统中,进程是资源分配的最小单位,线程是调度的基本单位.Linux是现代的32位或64位的支持多线程的操作系统,不过Linux是一种以轻量级进程作为线程,多 ...

  7. 【Android】ImageMap,图片地图

    https://github.com/CFutureTeam/android-image-map package com.*.imagemap; import *.imagemap.ImageMap; ...

  8. innodb的innodb_buffer_pool_size和MyISAM的key_buffer_size(转自:http://www.java123.net/898181.html)

    一. key_buffer_size 对MyISAM表来说非常重要. 如果只是使用MyISAM表,可以把它设置为可用内存的 -%.合理的值取决于索引大小.数据量以及负载 -- 记住,MyISAM表会使 ...

  9. redis link 链表结构

    lpush key value 作用: 把值插入到链接头部 rpop key 作用: 返回并删除链表尾元素 lrange key start stop 作用: 返回链表中[start ,stop]中的 ...

  10. 170808、生成为CVS文件

    /** * Desc : 生成为CVS文件 * User : RICK * @param data 源数据List * @param map csv文件的列表头map * @param outPutP ...