Ember.js 入门指南——番外篇,路由、模板的执行、渲染顺序

在Ember中路由和模板的执行都是有一定顺序的,它们的顺序为:主路由à子路由1à子路由2à子路由3à……。模板渲染的顺序与路由执行顺序刚好相反,从最后一个模板开始解析渲染。

       注意:模板的渲染是在所有路由执行完之后,从最后一个模板开始。关于这一点下面的代码会演示验证,官网教程有介绍,点击查看

比如有一路由格式为“application/posts/detail/comments/comment”,此时路由执行的顺序为:application/postsàdetailàcommentsàcomment,application是项目默认的路由,用户自定义的所有路由都是application的子路由(默认情况下),相对应的模板也是这样,所有用户自定义的模板都是application.hbs的子模板。如果你要修改模板的渲染层次你可以在route中重写renderTemplate回调函数,在函数内使用render方法指定要渲染的模板(如:render(“other”),渲染到other这个模板上)更多有关信息请查看这里。并且它们对应的文件模板结构如下图:

路由与模板是相对应的,所以模板的目录结构与路由的目录结构是一致的。

你有两种方式构建上述目录:

  1. 手动创建
  2. 使用命令,比如创建comment.js使用命令:ember generate route posts/detail/comments/comment,Ember CLI会自动为我们创建目录和文件。

创建好目录结构之后我们添加一些代码到每个文件。运行项目之后你就会一目了然了……。

下面我按前面讲的路由执行顺序分别列出每个文件的内容。

//  app/routes/posts.js
 
import Ember from ‘ember‘;
 
export default Ember.Route.extend({
       model: function() {
              console.log(‘running in posts...‘);
              return { id: 1, routeName: ‘The route is posts‘};
       }
      
});
import Ember from ‘ember‘;
 
export default Ember.Route.extend({
 
       model: function(params) {
              console.log(‘params id = ‘ + params.post_id);
              console.log(‘running in detail....‘);
 
              return { id: 1, routeName: ‘The route is detail..‘ };
       }
});
//  app/routes/posts/detail.js
 
import Ember from ‘ember‘;
 
export default Ember.Route.extend({
 
       model: function(params) {
              console.log(‘params id = ‘ + params.post_id);
              console.log(‘running in detail....‘);
 
              return { id: 1, routeName: ‘The route is detail..‘ };
       }
});
//  app/routes/posts/detail/comments.js
 
import Ember from ‘ember‘;
 
export default Ember.Route.extend({
       model: function() {
              console.log(‘running in comments...‘);
              return { id: 1, routName: ‘The route is comments....‘};
       }
});
//  app/routes/posts/detail/comments/comment.js
 
import Ember from ‘ember‘;
 
export default Ember.Route.extend({
       model: function(params) {
              console.log(‘params id = ‘ + params.post_id);
              console.log(‘running in comment...‘);
              return { id: 1, routeName: ‘The route is comment...‘};
       }
});

下面是模板各个文件的内容。其列出才顺序与路由的顺序一致。

<!--  //  app/templates/posts.hbs  -->
 
<!-- 所有的子路由对应的模板都会渲染到outlet上 -->
{{model.routeName}} >> {{outlet}}
<!-- // app/templates/posts/detail.hbs -->
 
<!-- 所有的子路由对应的模板都会渲染到outlet上 -->
{{model.routeName}} >> {{outlet}}
<!-- // app/templates/posts/detail/comments.hbs -->
 
<!-- 所有的子路由对应的模板都会渲染到outlet上 -->
{{model.routeName}} >> {{outlet}}
<!-- // app/templates/posts/detail/comments/comment.hbs -->
 
<!-- 所有的子路由对应的模板都会渲染到outlet上 -->
{{model.routeName}} >> {{outlet}}

下图是路由执行的顺序,并且在执行的过程中渲染路由对应的模板。

从上图中可用清楚的看到当你运行一个URL时,与URL相关的路由是怎么执行的。

  1. 执行主路由(默认是application),此时进入到路由的model回调方法,并且返回了一个对象“{ id: 1, routeName: ‘The route is application...‘ }”,执行完回调之后继续转到子路由执行直到最后一个路由执行完毕,所有的路由执行完毕之后开始渲染页面。
  2. 页面的渲染则是从最后一个路由对应的模板开始,并沿着最近的父模板往回渲染。

为了验证是否是这样的执行顺序,下面修改detail.js和comments.js。在代码中加入一个模拟休眠的操作。

//  app/routes/posts/detail.js
 
import Ember from ‘ember‘;
 
export default Ember.Route.extend({
 
       model: function(params) {
              console.log(‘params id = ‘ + params.post_id);
              console.log(‘running in detail....‘);
 
              //  执行一个循环,模拟休眠
              for (var i = 0; i < 10000000000; i++) {
                    
              }
              console.log(‘The comment route executed...‘);
 
 
              return { id: 1, routeName: ‘The route is detail..‘ };
       }
});
//  app/routes/posts/detail/comments.js
 
import Ember from ‘ember‘;
 
export default Ember.Route.extend({
       model: function(params) {
              console.log(‘params id = ‘ + params.post_id);
              console.log(‘running in comment...‘);
              //  执行一个循环,模拟休眠
              for (var i = 0; i < 10000000000; i++) {
                    
              }
 
              return { id: 1, routeName: ‘The route is comment...‘};
       }
});

刷新页面,注意查看控制台输出信息和页面显示的内容。

新开一个窗口,执行URL:http://localhost:4200/posts/2/comments

控制台输出到这里时处理等待(执行for循环),此时已经执行了两个路由application和posts,并且正在执行detail,但是页面是空白的,没有任何HTML元素。

在detail路由执行完成之后转到路由comments。然后执行到for循环模拟休眠,此时页面仍然是没有任何HTML元素。然后等到所有route执行完毕之后,界面才显示model回调里设置的信息。

每个子路由设置的信息都会渲染到最近一个父路由对应模板的“{{outlet}}”上面。

  1. 渲染comment

    得到的内如为:“comment渲染完成”

  2. 渲染comment最近的父模板comments

    得到的内容为:“comment渲染完成 comments渲染完成”

  3. 渲染comments最近的父模板detail

    得到的内容为:“comment渲染完成 comments渲染完成 detail渲染完成”

  4. 渲染detail最近的父模板posts

    得到的内容为:“comment渲染完成 comments渲染完成 detail渲染完成 posts渲染完成”

  5. 渲染posts最近的父模板application

    得到的内容为:“comment渲染完成 comments渲染完成 detail渲染完成 posts渲染完成 application渲染完成”

一句话:子模板的都会渲染到父模板的{{outlet}}上,最终所有的模板都会被渲染到application的{{outlet}}上。

    在设计界面布局的时候就要注意{{outlet}}放置的位置,{{outlet}}就像一个HTML组件一样任由你放置。

时间: 2024-09-28 05:22:52

Ember.js 入门指南——番外篇,路由、模板的执行、渲染顺序的相关文章

Ember.js 入门指南——总目录

Ember.js 是什么?我想对于想学习它的人应该知道它是个什么东西,如果你想了解那就赶紧去 Google 或者百度,本系列教程是通过学习官网教程然后摘抄个人觉得比较重要的部分,加上学习实例整合而成,如有疏漏欢迎提出修改意见,一起成长! Ember官网:http://emberjs.com/ 教程官网:http://guides.emberjs.com/v2.0.0/ 在此简单介绍下 Ember: Ember是一个雄心勃勃的Web应用程序,消除了样板,并提供了一个标准的应用程序架构的JavaSc

Ember.js 入门指南——模板渲染

路由的另一个重要职责是渲染同名字的模板. 比如下面的路由设置,posts路由渲染模板posts.hbs,路由new渲染模板posts/new.hbs. Router.map(function() {      this.route('posts', function() {      this.route('new');   }); }); 每一个模板都会渲染到父模板的{{outlet}}上.比如上面的路由设置模板posts.hbs会渲染到模板application.hbs的{{outlet}}

Ember.js 入门指南——异步路由

本文将为你介绍路由的高级特性,这些高级特性可以用于处理项目复杂的异步逻辑. 关于单词promises,直译是承诺,但是个人觉得还是使用原文吧.读起来顺畅点. 1,promises(承诺) Ember的路由处理异步逻辑的方式是使用promises.简而言之,promises就是一个表示最终结果的对象.这个对象可能是fulfill(成功获取最终结果)也可能是reject(获取结果失败).为了获取这个最终值,或者是处理promises失败的情况都可以使用then方法,这个方法接受两个可选的回调方法,一

Ember.js 入门指南——路由简介

从本文开始,将为大家介绍路由(route),如果你看过前面的<Ember.js 入门指南--{{link-to}} 助手>这篇文章应该初步了解了route.不过在这篇文章中只是简单介绍了路由是定义.路由层次,更深入的route将从本文开始逐一介绍. 当用户使用你的应用时,应用要在不同的状态之间切换.Ember提供了很多工具用于管理那些因应用规模改变而改变的状态. 讲route前先了解URL,在应用中大概会会有如下方式设置URL: 用户第一次加载应用的时: 用户手动改变URL,比如点击按钮之后跳

Ember.js 入门指南——路由定义

当你的应用启动的时候,路由器就会匹配当前的URL到你定义的路由上.然后按照定义的路由层次逐个加载数据.设置应用程序状态.渲染路由对应的模板. 1,基本路由 在app/router.js的map方法里定义的路由会映射到当前的URL.当map方法被调用的时候方法体内的route方法就会创建路由. 下面使用Ember CLI命令创建两个路由: ember generate route about ember generate route favorites 命令执行完之后你可在你的项目目录app/ro

Ember.js 入门指南——控制器(controller)

ember new chapter5_controllers cd chapter5_controllers ember server 从本篇开始进入第五章控制器,controller在Ember2.0开始越来越精简了,职责也更加单一--处理逻辑. 下面是准备工作. 从新创建一个Ember项目,仍旧使用的是Ember CLI命令创建. 在浏览器执行项目,看到如下信息说明项目搭建成功. Welcome to Ember 1,控制器简介 控制器与组件非常相似,由此,在未来的新版本中很有可能组件将会完

Ember.js 入门指南——model简介2

本文接上一篇<Ember.js 入门指南--model简介1>. 2,核心概念 声明:下面简介内摘抄至http://www.emberjs.cn/guides/models/#toc_. 1,store store是应用存放记录的中心仓库.你可以认为store是应用的所有数据的缓存.应用的控制器和路由都可以访问这个共享的store:当它们需要显示或者修改一个记录时,首先就需要访问store. DS.Store的实例会被自动创建,并且该实例被应用中所有的对象所共享. store可以看做是一个缓存

Ember.js 入门指南--目录

本系列文章全部从(http://ibeginner.sinaapp.com/)迁移过来,欢迎访问原网站. Ember.js 是什么?我想对于想学习它的人应该知道它是个什么东西,如果你想了解那就赶紧去 Google 或者百度,本系列教程是通过学习官网教程然后摘抄个人觉得比较重要的部分,加上学习实例整合而成,如有疏漏欢迎提出修改意见,一起成长! Ember官网:http://emberjs.com/ 教程官网:http://guides.emberjs.com/v2.0.0/ 在此简单介绍下 Emb

Ember.js 入门指南——属性传递

1,传递参数到组件上 每个组件都是相对独立的,因此任何组件所需的数据都需要通过组件的属性把数据传递到组件中. 比如上篇<Ember.js 入门指南--组件定义>的第三点"{{component item.pn post=item}}"就是通过属性post把数据传递到组件foo-component或者bar-component上.如果在index.hbs中是如下方式调用组件那么渲染之后的页面是空的. {{component item.pn}} 请读者自己修改index.hbs