同构JavaScript框架和库最近引起了很多关注。 同构JavaScript应用程序是用JavaScript编写的应用程序,可以在客户端和服务器上运行。 因此,您可以编写一次代码,然后在服务器上执行以呈现静态页面,并在客户端上执行以实现快速交互。
在本文中,我们将探索和开始使用由Airbnb团队开发的开源库Rendr 。 该库最初的构建目标是为公司在Backbone.js和Node.js上运行的移动应用程序提供支持。 后来,该公司将其设为一个开源项目,这使该项目获得了很大的吸引力。
什么是伦德尔
Rendr的基本思想是通过为两端编写通用代码来允许在客户端和服务器上呈现Backbone.js应用程序。 这允许在浏览器中执行JavaScript代码之前,通过服务器呈现网页内容。 一旦完成初始页面加载并且浏览器已加载所有客户端框架,则应用程序的进一步路由将由客户端Backbone.js处理。 Rendr并不是一个完整的框架,它具有以下设计目标:
- 编写与环境无关的应用程序逻辑
- 减少
if(server) { ... } else { ... }
结构 - 与RESTful API进行通信,就像其他任何Backbone应用程序一样
- 隐藏库的复杂性
- 排除服务器端DOM
在本教程中,我们将使用GitHub浏览器探索一个简单的Rendr应用程序,该浏览器可通过GitHub REST API获取存储库和用户的数据。 此小应用程序是Rendr示例示例的一部分。 您可以从GitHub存储库下载这些示例 。 在这里,我们将探索基本的“ 00_simple”应用程序。
在加深主题之前,让我们了解一下应用程序的外观。 它包含以下部分:
- 存储库列表视图:存储库的列表部分将获取并列出一些GitHub存储库
- 回购视图 :单击特定的存储库,将打开其信息页面
- 用户列表视图 :用户列表部分获取并列出GitHub用户
- 用户视图 :单击特定用户,将打开用户配置文件视图,其中包含一些基本用户详细信息及其存储库
以下屏幕截图显示了我们的用户视图的外观
如何安装Rendr
Rendr需要先安装Node.js服务器。 如果需要安装,可以从Node.js主页下载 。 之后,我们必须安装一个JavaScript任务运行器Grunt ,它可以使重复的任务自动化,如缩小,编译,单元测试等。 您可以通过运行以下命令来安装它:
npm install -g grunt-cli
如果您想了解有关Grunt的更多信息,建议您阅读一下SitePoint上发布的以下文章:
现在,运行以下命令以安装项目的所有依赖项:
npm install
最后,运行Web服务器,通过执行以下命令来启动项目:
grunt server
服务器启动后,该应用程序将在默认端口3030上运行,您可以通过在浏览器中打开localhost:3030
来访问它。 现在让我们了解如何设计该应用程序。
应用结构
在您选择的IDE中打开“ 00_simple”应用程序,并查看其结构。 您会注意到,它与任何Backbone.js应用程序非常相似,其中某些约定来自Express和Rails,如下图所示。
至于我们的Rendr应用程序的各个组件,它包含五个基本部分:主页,用户视图,用户列表视图,回购视图和回购列表视图。 应用程序中的每个文件夹(模型,视图,控制器,集合等)都将包含所有这些部分的代码。 但是,我们将主要集中在“用户列表视图”上,这是我们将详细讨论的唯一模型。
初始化客户端/服务器路由配置
既然我们已经知道Rendr应用程序的基本结构,那么让我们看看初始化客户端和配置服务器所需要做的工作。 有关请求,控制器和要路由的动作(或方法)的信息包含在名为routes.js
的文件中:
module.exports = function(match) {
match('', 'home#index');
match('repos', 'repos#index');
match('repos/:owner/:name', 'repos#show');
match('users' , 'users#index');
match('users/:login', 'users#show');
initi};
上面的代码初始化了请求URL输入与该请求应路由到的控制器/动作之间的映射。 例如,空白的URL输入将被路由到home控制器的index
方法,而具有这种结构repos/:owner/:name
的URL输入将被路由到repos控制器的show
方法,使用match('', 'home#index')
和match('repos/:owner/:name', 'repos#show')
分别匹配。
初始化配置
在本节中,我们将了解如何使用index.js
或server.js
初始化配置,例如dataAdapterConfig
, apiPath
, dataAdapter
或defaultEngine
。 例如,在我们的应用程序中,可以在index.js
dataAdapterConfig
部分中找到调用GitHub API所需的配置。
var dataAdapterConfig = {
'default': {
host: 'api.github.com',
protocol: 'https'
}
};
然后,使用以下示例代码将此dataAdapterConfig
对象传递给rendr.createServer()
方法以初始化Rendr服务器。
var server = rendr.createServer({
dataAdapterConfig: dataAdapterConfig
});
该应用程序模型还执行以下任务:启动服务器,初始化访存程序,modelUtils,使用配置的定义值定义要使用的模板适配器和模板引擎。
引导数据并初始化客户端路由器
如果查看布局文件app/templates/_layout.hbs
,则会发现以下代码来引导默认应用程序数据,并使用App.start()
启动客户端路由器。
var App = window.App = new (require('app/app'))({{json appData}});
App.bootstrapData({{json bootstrappedData}});
App.start();
初始化模板适配器和模板引擎
默认情况下,Rendr附带HandleBar.js作为模板适配器和模板引擎。 但是,您可以通过在app.js
文件中配置其他适配器和引擎来使用它们。
例如,Rendr支持Emblem.js作为另一个模板适配器。 因此,如果希望使用Emblem.js而不是默认的HandleBar.js,则需要在App.js
进行以下配置。
module.exports = BaseApp.extend({
defaults: {
templateAdapter: 'rendr-emblem'
}
});
同样,如果您想使用特定的模板引擎,则可以使用以下配置在App.js
文件中对其进行配置:
module.exports = BaseApp.extend({
defaults: {
templateEngine: 'handlebars'
}
});
观看次数
Rendr视图扩展了Backbone.js视图。 您可以从下图看到,我们应用程序中的views
文件夹的结构包含用于home,user和repos的文件夹。 它还包含base.js
和user_repos_view.js
视图文件。
要查看显示用户列表的视图,请打开app/views/index.js
文件。 在这里,您将找到以下代码:
var BaseView = require('../base');
module.exports = BaseView.extend({ className: 'users\_index_view' });
module.exports.id = 'users/index';
上面的代码显示了如何扩展Rendr基础视图,进而扩展Backbone.js视图。 这些视图还需要导出一个标识符,该标识符将用于在这些视图中获取和显示数据。 在我们的示例中,此标识符为users/index
。
请注意,这是视图显示方式的非常基本的示例。 Rendr中的视图能够在客户端和服务器之间呈现内容,提高性能,延迟加载并支持各种方法,例如attach()
, getAttributes()
, getHTML()
, getInnerHTML()
等。
范本
Rendr模板用于定义要在视图上呈现的数据的结构。 模板引擎(例如Underscore,Handlebars,Mustache等)将编译脚本,用JSON对象中的真实数据替换变量,并将HTML代码注入指定的位置。 下图显示了我们应用程序中templates
文件夹的结构,其中包含默认的_layout.hbs
以及用于home,repos和user的单个文件夹。
如果打开app/templates/users/index.hbs
文件,您会看到它为我们的用户列表视图定义了模板。 该文件遍历模型中的所有用户,并将其显示为超链接。
<ul>
{{#each models}}
<li>
<a href="/users/{{login}}">{{login}}</a>;
</li>
{{/each}}
</ul>
控制器
现在我们已经有了视图和模板,我们将研究应用程序的另一个重要方面:控制器。 控制器定义访问URL时路由器将调用的功能。 它们遵循“ name_controller.js”的命名约定。 controllers
文件夹的结构如下所示,其中包含用于家庭,仓库和用户的控制器文件。
如果打开users_controller.js
文件,您将找到以下代码片段:
index: function(params, callback) {
var spec = {
collection: {collection: 'Users', params: params}
};
this.app.fetch(spec, function(err, result) {
callback(err, result);
});
}
上面的代码定义了index方法。 在这里, spec
变量指定从用户集合中获取数据(我们将在稍后看到集合是什么,但现在将其视为一组模型),然后将此spec
对象传递给app.fetch
方法。
楷模
Rendr模型扩展了Backbone.js模型,并且可以在客户端和服务器上运行。 如果您在我们的应用程序中查看models
的文件夹结构,则其中包含用于回购,用户和基础的模型文件。
打开user.js
文件( app/models/user.js
),其中包含以下代码以从GitHub API中获取用户数据:
var Base = require('./base');
module.exports = Base.extend({ url: '/users/:login', idAttribute: 'login' });
module.exports.id = 'User';
上面的代码扩展了基础模型类,并定义了URL(类似于Backbone的model.url
),您可以从中获取模型数据。 在我们的案例中,当我们单击用户列表视图上的特定用户链接时,将使用此模型来获取数据。
馆藏
Rendr集合(源自Backbone.js集合)是有序的模型集,用于委派一组模型的事件,侦听集合中模型的添加或删除以及将这些集合与服务器同步。 除了Backbone.js集合的功能外,Rendr还具有两项新功能,它们的作用类似于集合存储,并且可以在客户端或服务器上以相同的方式同步集合。 我们应用程序中的collections文件夹由基础,存储库和用户的collection组成。
打开users.js
集合,其中包含以下代码:
var User = require('../models/user') , Base = require('./base');
module.exports = Base.extend({ model: User, url: '/users' });
module.exports.id = 'Users';
此代码首先扩展基础集合,然后定义该集合的模型(即用户模型),最后指定可以从中获取数据的URL。 在我们的案例中,集合通过以{API-URL/users}
格式传递URL从GitHub REST API获取数据。
结论
在本文中,我们介绍了Rendr,这是最流行的同构JavaScript库之一。 在一个基本的入门示例的帮助下,我们研究了典型的Rendr应用程序的设计,组件和流程。 尽管我们触及了Rendr的大多数重要概念,但是您还可以加深其他有趣的事情。 但是,由于目前产品文档有限,因此在Rendr上进行更多探索的最佳地方仍然是GitHub参考和我们下载的其他高级示例。 如有任何问题或建议,请随时尝试使用Rendr,并分享您的评论。
本教程对开始开发Rendr应用程序可能需要的所有基本概念以及它的各个组件如何结合在一起进行了详细的概述。 我们已经创建了绑定到模板的视图,并查看如何将它们组合以在我们的应用程序中显示数据。
发出请求时,路由器设置会根据URL输入定义要调用的控制器和方法。 该控制器和方法定义了可以从中获取数据的模型或集合。 模型或集合进行实际的数据交互,并通过API或数据库获取数据。 最后,从此模型或集合返回的数据将绑定到我们在第一步中创建的模板。