随着时间的推移,Discourse 的复杂性不断增加,对于初学者来说,要理解数据是如何从后端的 Ruby on Rails 应用程序一路到达前端的 Ember.js 应用程序是令人生畏的。
本教程旨在展示 Discourse 中请求的完整生命周期,并解释如果您想在我们的应用程序中构建一个带有自己 URL 的新页面所需的步骤。
URL 优先
我总是倾向于从访问它们的 URL 角度来思考功能。例如,假设我们想构建一个管理功能,显示我在处理 Discourse 时吃的最后一块零食。一个合适的 URL 将是 /admin/snack
在这种情况下:
-
在浏览器中访问
/admin/snack应该使用“全栈”显示零食,换句话说,Ember 应用程序将被加载,它将请求显示零食所需的数据。 -
访问
/admin/snack.json应返回零食本身的 JSON 数据。
服务器端(Ruby on Rails)
让我们从为零食创建一个新的控制器开始。
app/controllers/admin/snack_controller.rb
class Admin::SnackController < Admin::AdminController
def index
render json: { name: "donut", description: "delicious!" }
end
end
在这种情况下,我们继承自 Admin::AdminController 以获得所有安全检查,以确保查看此控制器的用户是管理员。在我们能够访问我们的控制器之前,我们只需要再做一件事,那就是向 config/routes.rb 添加一行:
找到如下所示的代码块:
namespace :admin, constraints: StaffConstraint.new do
# lots of stuff
end
并在其中添加此行:
get 'snack' => 'snack#index'
完成后,您应该能够在浏览器中访问 /admin/snack.json,您将看到零食的 JSON!我们的零食 API 似乎工作正常 ![]()
当然,随着您构建功能以增加更多复杂性,您可能不会像这样只从控制器返回硬编码的 JSON,而是会查询数据库并以这种方式返回它。
客户端(Ember.js)
如果打开浏览器并访问 /admin/snack(不带 .json),您会看到 Discourse 显示“哎呀!该页面不存在。”——这是因为我们的前端 Ember 应用程序中没有任何内容来响应该路由。让我们添加一个Handlebars 模板来显示我们的零食:
app/assets/javascripts/admin/templates/snack.hbs
<h1>{{model.name}}</h1>
<hr />
<p>{{model.description}}</p>
而且,就像在 Rails API 端一样,我们需要连接路由。打开文件 app/assets/javascripts/admin/routes/admin-route-map.js 并查找 export default function() 方法。添加以下行:
this.route("snack");
我们在 Ember 端还有最后一件事要做,那就是让 Ember 应用程序执行 AJAX 请求以从服务器获取我们的 JSON。让我们创建最后一个文件。这将是一个Ember 路由。当进入路由时,它的 model() 函数将被调用,所以我们将在其中进行 ajax 调用:
app/assets/javascripts/admin/routes/admin-snack.js
import { ajax } from "discourse/lib/ajax";
export default Ember.Route.extend({
model() {
return ajax("/admin/snack.json");
},
});
现在,您可以打开浏览器访问 /admin/snack,您应该会在页面上看到零食的详细信息已渲染!
总结
-
在浏览器中打开
/admin/snack会启动 Ember 应用程序 -
Ember 应用程序路由器说
snack应该是路由 -
snack的 Ember.Route 对/admin/snack.json发起 AJAX 请求 -
Rails 应用程序路由器说这应该是
admin_snack controller -
admin_snack_controller返回 JSON -
Ember 应用程序获取 JSON 并渲染 Handlebars 模板
后续步骤
我写了一篇后续教程,介绍如何在 Discourse 中添加 Ember 组件。
本文档已版本控制 - 在 github 上 建议更改。