Sails.js 是一個新興的 Node.js 框架,專注於自由和智慧預設。在本文中,我們將了解 Sails 提供的一些開箱即用的資料功能,以便輕鬆製作複雜的應用程式。
選擇 Sails 的原因由 Sails 的創建者 Mike McNeil 說得最好,「Sails 的創建是出於需要」。您看到的許多框架幾乎都是為學術方面而構建的,這些框架通常會促進最佳實踐,並為開發人員創建一個平台,以便更快或更好地創建東西。
另一方面,Sails 是為生產而創建的,它並不是試圖為您提供新的語法或平台,而是一個堅實的基礎,旨在快速創建「客戶工作」。對比可能很微妙,但還是有一些明顯的差異。
為了說明我所指的內容,讓我們來看看 Meteor。 Meteor 可能是當今領先的 JS 平台,但它是框架的一個主要示例,只是為了框架。現在這並不是一件壞事,我是 Meteor 的大力支持者,我的意思是,他們著手建立一個框架並且做得很好,另一方面 Mike 著手讓客戶工作更快。風帆只是達到目的的手段。
在 Meteor 中,幾乎所有內容都被抽象化,您可以使用 JavaScript 加上 Meteor API 來對所有內容進行編碼。而 Sails 並不是一個新平台,因此沒有隱藏任何內容。
它建立在 Socket.io 和流行的 Express 框架之上,您可以在本機上完整地存取它們。您開始看到差異了嗎?
此外,由於 Sails 首先是針對生產,因此它具有多種擴展和安全選項。
有很多內容要談,但在本文中,我想重點討論 Sails 如何處理數據,以及如何利用 Sails 的一些更高級的功能來執行一些非常酷的操作。
萬一您尚未安裝 Sails,您可以透過 NPM 執行以下命令來安裝:
sudo npm install -g sails
現在,在討論 Sails 之前,讓我們先談談 Socket.io 和 Express。如果您有興趣的話,Andrew Burgess 有一個關於 Express 的很好的高級系列,但我將在這裡介紹這兩個庫的相關基礎知識:
Socket.io 是一個 pub/sub 庫,它在伺服器和用戶端上運行,並且允許它們透過 Web 套接字進行通訊。
一個簡短的範例可能如下所示:
//Code For Server var io = require("socket.io"); io.sockets.on("connection", function (sock) { sock.emit("welcomeMessage", { hello: "world" }); } io.listen(80);
此程式碼首先需要socket.io
庫,偵聽連接,然後當另一個套接字連接時,它將向其發送一條訊息,發送給welcomeMessage
事件,最後傳遞一些JSON .
接下來,在客戶端上您將撰寫以下內容:
//Code For Client var sock = io.connect('http://localhost'); sock.on('welcomeMessage', function (json) { //Handle Event Received });
在這裡,我們連接到伺服器並監聽我們剛剛建立的 welcomeMessage
事件。正如您所看到的,這是一個相當簡單的發布/訂閱伺服器,它是雙向的(客戶端也可以向伺服器發送訊息)。
現在讓我們來看看 Express:
快速路線最簡單的形式可能類似於:
app.get('/users', function(req, res) { res.send("Hello from '/users' !"); });
這定義了一個簡單的路由,這樣當用戶訪問您網站的地址並嘗試訪問/users
頁面時,他們將看到消息“Hello from '/users' !”
。
So Express 是一個處理 HTTP 請求的框架,而 Socket.io 是一個 websocket 通訊庫。 Sails 團隊所做的是將所有 Express 路由內部對應到 Socket.io。這意味著,您可以透過 Web 套接字呼叫任何 HTTP 路由。
現在這太酷了!但是,仍然缺少一塊拼圖,那就是帆藍圖。
Sails 讓您可以像在其他框架中一樣產生模型,不同之處在於,Sails 還可以產生生產就緒的 RESTfull API 來配合它們。這意味著,如果您產生名為「users
」的模型,您可以立即對「/users
」資源執行 RESTfull 查詢,而無需任何編碼。
如果您不熟悉 RESTful API,它只是一種存取資料的方式,其中 CRUD 操作會對應到各種 HTTP 方法。
因此,對 '/users
' 的 GET
請求將獲取所有用戶,POST
請求將建立一個新用戶,等等。
那麼這一切又意味著什麼?
這意味著我們擁有完整的 RESTfull API,透過 Sails 映射到 Socket.io,無需編寫任何程式碼!
但是為什麼套接字比 Ajax 請求更擅長檢索資料呢?好吧,除了是一個更精簡的協議之外,套接字還保持開放狀態以進行雙向通信,Sails 已經利用了這一點。 Sails 不僅會向您傳遞數據,還會自動為您訂閱該資料庫的更新,每當新增、刪除或更新某些內容時,您的用戶端都會透過Web 套接字收到通知,讓您了解相關情況。 < /p>
這就是 Sails 如此出色的原因!
我想讨论的下一个主题是 Backbone 集成,因为如果您不使用 JavaScript 框架,那么您就做错了。
考虑到这一点,Sails 和 Backbone 是完美的组合。 Backbone 与 Sails 一样,非常不显眼,它的所有功能都是可用的,能够被覆盖,并且是可选的。
如果您之前使用过 Backbone,您可能知道它与 REST API 本地连接,因此开箱即用,您可以将前端上的数据与 Sails 应用程序同步。
但是现在已经说得够多了,让我们通过创建一个基本的聊天应用程序来看看所有这一切的实际情况。首先,打开终端窗口并输入:
sails new ChatApp cd ChatApp sails generate model users sails generate model messages sails generate controller messages sails generate controller main
这将为我们创建一个新应用程序并生成一些文件。从上面您可以看到,您可以生成两种不同的资源;模型和控制器。如果您熟悉 MVC 设计模式,那么您应该知道它们是什么,但简而言之,模型是您的数据,控制器保存您的逻辑代码。因此,我们需要两个集合,一个用于保存用户,另一个用于保存消息。
接下来,对于控制器,我们需要一个来处理页面路由,我将其命名为“main
”,然后我们有第二个控制器,名为“messages
”。现在你可能想知道为什么我创建了一个与我们的 messages
模型同名的控制器?好吧,如果您还记得的话,我说过 Sails 可以为您创建 REST API。发生的情况是,通过创建与模型同名的空白控制器,Sails 将知道回退并为相应的资源构建 REST API。
因此,我们已经为 messages
模型创建了一个控制器,但不需要为 users 模型创建一个控制器,所以我将其省略。这就是创建模型和控制器的全部内容。
接下来,让我们设置一些路线。
路由始终是一个安全的起点,因为您通常很清楚要创建哪些页面。
所以打开 config
文件夹中的 routes.js
文件,一开始可能看起来有点不知所措,但是如果你删除所有注释并在以下路由中添加留下这样的东西:
module.exports.routes = { '/' : { controller: 'main', action: 'index' }, '/signup' : { controller: 'main', action: 'signup' }, '/login' : { controller: 'main', action: 'login' }, '/chat' : { controller: 'main', action: 'chat' } };
我们有一个主页、一个聊天页面,以及两个用于处理登录和注册页面的页面。我将它们全部放在同一个控制器中,但在 Sails 中,您可以创建任意数量的控制器。
接下来,我们看一下生成的 messages
模型,该模型位于“api > models > Messages.js
”。我们需要将必要的列添加到我们的模型中。现在这不是绝对必要的,但它会为我们创建一些我们可以使用的辅助函数:
//Messages Model module.exports = { attributes : { userId: 'INT', username: 'STRING', message: 'STRING' } };
对于 messages
模型,我们从该消息所属用户的 id
开始,一个 username
这样我们就不必单独查询它,然后是实际的 message
。< /p>
现在让我们填写用户的模型:
//Users Model module.exports = { attributes : { username: 'STRING', password: 'STRING' } };
就是这样,我们只有 username
和 password
属性。下一步是在 MainController
中创建路由函数。
因此,打开MainController
,可以在“api>controllers>MainController.js
”中找到它。让我们首先为上面定义的每个路由创建一个函数:
var MainController = { index: function (req, res) { }, signup: function (req, res) { }, login: function (req, res) { }, chat: function (req, res) { } }; module.exports = MainController;
如果您熟悉 Express,那么您会很高兴看到这些功能是标准的 Express 路线功能。它们接收两个变量,req
用于 HTTP 请求,res
用于创建响应。
遵循 MVC 模式,Sails 提供了渲染视图的功能。主页不需要任何特殊的东西,所以我们只渲染视图。
index: function (req, res) { res.view(); },
Sails 更倾向于约定优于配置,因此当您调用 res.view();
时,Sails 将使用以下模式查找视图文件(默认情况下带有 .ejs
扩展名): '视图 > 控制器名称 > 方法名称.ejs
'。因此,对于此调用,它将搜索“views>main>index.ejs
”。还值得注意的是,这些视图仅包含页面的视图特定部分。如果你看一下'views>layout.ejs
',你会在中间看到一个对 <%- body %>
的调用,这是你的视图文件将被插入的地方。默认情况下,它使用“layout.ejs
”文件,但您只需将布局名称传递到名为“layout”的属性下的 res.view()
函数即可使用其他布局文件。例如: 'res.view( { layout: "other.ejs" } );
'。
我将使用默认布局文件并进行一些小调整,我将添加 jQuery、Backbone 和 Underscore。因此,在 'layout.ejs
' 文件中,在关闭 </head>
标记之前,添加以下行:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
完成后,我们现在就可以创建主页了。
让我们在 views
文件夹中创建一个名为 main
的新文件夹,并在新的 main
文件夹中创建一个名为“index.ejs”的新文件。
在文件中,我们只创建一个登录和注册表单:
<h1>Code Chat</h1> <div> <h3>Login</h3> <input type="text" id="loginName" placeholder="name" /> <input type="password" id="loginPassword" placeholder="password" /> <button id="loginButton">Login</button> </div> <div> <h3>Signup</h3> <input type="text" id="signupName" placeholder="name" /> <input type="password" id="signupPassword" placeholder="password" /> <input type="password" id="signupConfirmPassword" placeholder="confirm password" /> <button id="signupButton">Signup</button> </div>
非常简单,只是要点。
接下来我们需要添加一些 JS 来与服务器进行通信。现在这不是 Sails 特有的,我们只是通过 jQuery 向 Sails 服务器发送 AJAX 请求。
此代码可以包含在页面本身中,也可以通过单独的 JS 文件加载。为了方便起见,我将其放在同一页面的底部:
<script> $("#loginButton").click(function(){ var username = $("#loginName").val(); var password = $("#loginPassword").val(); if (username && password) { $.post( '/login', {username: username, password:password}, function () { window.location = "/chat"; } ).fail(function(res){ alert("Error: " + res.getResponseHeader("error")); }); } else { alert("A username and password is required"); } }); </script>
这只是标准的 JS 和 jQuery,我们正在监听登录按钮上的单击事件,确保填写用户名和密码字段,并将数据发布到 '/login
' 路由。如果登录成功,我们将用户重定向到聊天页面,否则将显示服务器返回的错误。
接下来,让我们为注册区域创建相同的内容:
$("#signupButton").click(function(){ var username = $("#signupName").val(); var password = $("#signupPassword").val(); var confirmPassword = $("#signupConfirmPassword").val(); if (username && password) { if (password === confirmPassword) { $.post( '/signup', {username: username, password:password}, function () { window.location = "/chat"; } ).fail(function(res){ alert("Error: " + res.getResponseHeader("error")); }); } else { alert("Passwords don't match"); } } else { alert("A username and password is required"); } });
这段代码几乎是相同的,以至于您可以将整个 Ajax 部分抽象为它自己的函数,但对于本教程来说这很好。
现在我们需要返回到“MainController
”并处理这两个路由,但在此之前,我想安装一个 Node 模块。我们需要对密码进行哈希处理,因为纯文本密码不是一件好事,甚至不利于演示!我发现了一个不错的模块,名为“password-hash”,由 David Wood 编写,效果很好。
要安装它,只需在终端中转到 Sails 应用程序的根目录并输入:npm install password-hash
。
安装完成后,让我们打开 MainController
并实现两个所需的路由。让我们从 signup
开始:
signup: function (req, res) { var username = req.param("username"); var password = req.param("password"); Users.findByUsername(username).done(function(err, usr){ if (err) { res.send(500, { error: "DB Error" }); } else if (usr) { res.send(400, {error: "Username already Taken"}); } else { var hasher = require("password-hash"); password = hasher.generate(password); Users.create({username: username, password: password}).done(function(error, user) { if (error) { res.send(500, {error: "DB Error"}); } else { req.session.user = user; res.send(user); } }); } }); }
这有点冗长,但我们在这里所做的只是从 POST 请求中读取用户名和密码,并确保用户名尚未被占用。你可以看到我也在使用我们刚刚安装的密码哈希器,它使用起来非常简单,只需将密码传递到生成方法中,它就会使用随机盐对其进行哈希处理。
还值得一提的是,在我们可能遇到错误或问题的每个可能位置,我们都会发回 HTTP 错误代码并通过名为“error
”的自定义标头返回消息,如果您请记住,我们正在索引页上的警报消息中显示。
另一个值得注意的点是,我们使用了一个名为“findByUsername
”的“神奇”函数,这是因为我们的用户模型中有一个 username
列。
最后,在底部您可以看到是否一切顺利,我们将用户存储在会话变量中,并以默认状态代码 200 返回它,这将告诉 jQuery AJAX 请求已成功。
接下来我们来编写登录函数:
login: function (req, res) { var username = req.param("username"); var password = req.param("password"); Users.findByUsername(username).done(function(err, usr) { if (err) { res.send(500, { error: "DB Error" }); } else { if (usr) { var hasher = require("password-hash"); if (hasher.verify(password, usr.password)) { req.session.user = usr; res.send(usr); } else { res.send(400, { error: "Wrong Password" }); } } else { res.send(404, { error: "User not Found" }); } } }); }
同样,这与之前的 signup
函数非常相似,我们正在搜索与从表单中发布的用户名相同的用户,如果找到,我们使用哈希器的 验证
方法。我们不能再次对密码进行哈希处理并将其传递到模型 find
函数的原因是因为哈希器使用随机盐,因此如果我们再次对密码进行哈希处理,它将等于其他内容。
其余代码相同;如果一切正常,我们将用户存储在会话中并返回它,否则我们会发回一条错误消息。
登录系统现已完成,我们终于可以继续构建聊天功能了。
由于我们将使用 Backbone 来获取消息,因此实际的路由功能将非常简单。这是完整的聊天功能:
chat: function (req, res) { if (req.session.user) { res.view({username: req.session.user.username}); } else { res.redirect('/'); } }
我们首先检查用户是否登录,如果检查成功,那么它将加载视图,并将会话中的用户名传递给它,否则我们只是重定向到主页。 p>
现在让我们在 main
文件夹中创建一个名为“chat.ejs
”的新视图。打开它,让我们创建一个简单的表单来发布新消息,并创建一个 div
容器来显示所有消息。
<h2>Welcome <%= username %></h2> <div id="newMessageForm"> <textarea id="message" placeholder="Enter your message here:"></textarea> <button id="postMessageButton">Add Message</button> </div> <div id="messagesContainer"> </div>
对于这个视图,我们只使用了一些非常标准的 HTML。唯一可能需要解释的是 <%= username %>
代码,这种编码风格并不是 Sails 特有的,它实际上是 EJS 的语法。这种语法与 PHP 的短标签非常相似。 <%
相当于 PHP 中的 <?
,<%=
与 <?=
相同。 EJS 的第一个片段允许您在页面上集成标准 JS 代码,而第二个片段则打印出其中的代码。这里我们只是打印出从控制器传入的用户名。
我们的聊天功能的其余部分将全部由 JavaScript 实现。首先,让我们看看如何使用标准 Backbone 编写聊天功能,然后我们将了解如何利用网络套接字。
在页面底部添加以下JS:
<script> var MessageModel = Backbone.Model.extend({ urlRoot: '/messages', }); var MessageCollection = Backbone.Collection.extend({ url: '/messages', model: MessageModel, }); var messages = new MessageCollection(); messages.fetch(); $("#postMessageButton").click(function(){ var messageText = $("#message").val(); messages.create({message: messageText}, {wait: true}); $("#message").val(""); }); </script>
由于 Sails 自动创建 Backbone 本身可以理解的 API,因此无需编写额外的服务器代码,因此没有比这更容易的了。这就是我在说 Sails 不是为了成为一个“框架”时所谈论的内容。它不会试图让您使用自己的语法,它是为了完成任务而设计的,正如您所看到的,它提供了。
要对其进行测试,请打开终端窗口并导航到 Sails 应用程序文件夹,然后输入“sails lift
”以启动它。默认情况下,它将启动到 http://localhost:1337
。现在只需注册并发布一些消息即可。
要查看您发布的消息,您可以 console.log
messages 变量,或者在浏览器控制台中查看它。现在我们接下来应该实现一个视图,以便我们可以在浏览器中看到发布的消息。
_.templateSettings = { interpolate : /\{\{(.+?)\}\}/g }; var MessagesView = Backbone.View.extend({ el: '#messagesContainer', initialize: function () { this.collection.on('add', this.render, this); this.render(); }, template: _.template("<div><p>{{ message }}</p></div>"), render: function () { this.$el.html(""); this.collection.each(function(msg){ this.$el.append(this.template(msg.toJSON())); }, this) } }); var mView = new MessagesView({collection: messages});
我们首先定义一个视图,将其附加到我们之前创建的 div,然后在集合上添加一个事件处理程序,以便在每次将新模型添加到集合时重新渲染 div。
您可以在顶部看到,我必须将默认的下划线设置从使用模板内部的 EJS 语法更改为使用 Mustache 的语法。这是因为该页面已经是一个 EJS 文档,因此它将在服务器上处理,而不是在 Underscore 中处理。
注意:我没有为此想出正则表达式,这归功于 Underscore 文档本身。
最后,在底部您可以看到我们创建了该视图的一个新实例,并向其传递了集合变量。
如果一切顺利,您现在应该在浏览器中看到您的消息,并且每当您创建新帖子时它都会更新。
现在您可能已经注意到,我们在提交帖子时没有设置 userId
或 username
,这是出于安全目的。
您不想将这种控制放在客户端。如果某人所要做的就是修改 JavaScript 变量来控制另一个用户的帐户,那么您将遇到一个大问题。
那么,你应该如何处理这个问题呢?嗯,当然有政策。
策略基本上是中间件,在实际 Web 请求之前运行,您可以根据需要在其中停止、修改甚至重定向请求。
对于此应用,让我们为我们的消息创建一个策略。策略应用于控制器,因此它们甚至可以在普通页面上运行,但在本教程中,我们只为 messages
模型使用一个策略。
在“api>policies
”文件夹中创建一个名为“MessagesPolicy.js”的文件,并输入以下内容:
module.exports = function (req, res, next) { if (req.session.user) { var action = req.param('action'); if (action == "create") { req.body.userId = req.session.user.id; req.body.username = req.session.user.username; } next(); } else { res.send("You Must Be Logged In", 403); } };
那么,这是怎么回事?您可以看到该函数类似于普通的路由函数,但区别在于第三个参数,它将调用堆栈中的下一个中间件。如果您对中间件的概念不熟悉,您可以将其想象为俄罗斯嵌套娃娃。每一层都会收到请求以及响应变量,并且可以根据需要对其进行修改。如果满足了所有的要求,该层就可以进一步传入,直到到达中心,这就是路由函数。
所以我们在这里检查用户是否已登录,如果用户未登录,我们将显示 403 错误并且请求在此结束。否则,(即用户已登录)我们调用 next();
来传递它。在上面代码的中间,是我们注入一些后置变量的地方。我们将此应用于“消息”控制器(基本上是 API)上的所有调用,因此我们获取操作并检查此请求是否正在尝试创建新消息,在这种情况下,我们为用户的 id
和 用户名
。
接下来,打开config文件夹中的policies.js
文件,并添加我们刚刚创建的策略。所以你的文件应该是这样的:
module.exports.policies = { '*': true, 'messages': 'MessagesPolicy' };
完成此操作后,我们需要删除所有旧记录,因为它们没有这些新信息。因此,关闭 Sails 服务器 (ctrl-c) 并在同一终端窗口中输入: rm -r .tmp
以删除临时数据库,让我们重新开始。
接下来,让我们将用户名添加到实际帖子中,因此在“chat.ejs”中将模板更改为:
template: _.template("<div><p><b>{{ username }}: </b>{{ message }}</p></div>"),
重新启动 Sails 服务器(再次使用 sails lift
)并注册另一个新用户来测试它。如果一切正常,您应该能够添加消息并在帖子中看到您的名字。
此时我们已经有了一个非常好的设置,我们使用 Backbone 和 API 自动获取帖子,此外我们还有一些基本的安全措施。问题是,当其他人发布消息时它不会更新。现在,您可以通过创建 JavaScript 间隔并轮询更新来解决此问题,但我们可以做得更好。
我之前提到过,Sails 利用 websockets 的双向功能来发布订阅数据的更新。使用这些更新,我们可以侦听消息表中的新添加内容并相应地更新集合。
因此,在 chat.ejs
文件中,让我们创建一种新的集合; SailsCollection:
var SailsCollection = Backbone.Collection.extend({ sailsCollection: "", socket: null, sync: function(method, model, options){ var where = {}; if (options.where) { where = { where: options.where } } if(typeof this.sailsCollection === "string" && this.sailsCollection !== "") { this.socket = io.connect(); this.socket.on("connect", _.bind(function(){ this.socket.request("/" + this.sailsCollection, where, _.bind(function(users){ this.set(users); }, this)); this.socket.on("message", _.bind(function(msg){ var m = msg.uri.split("/").pop(); if (m === "create") { this.add(msg.data); } else if (m === "update") { this.get(msg.data.id).set(msg.data); } else if (m === "destroy") { this.remove(this.get(msg.data.id)); } }, this)); }, this)); } else { console.log("Error: Cannot retrieve models because property 'sailsCollection' not set on the collection"); } } });
现在可能很长,但实际上很简单,让我们来看看。我们首先向 Collection 对象添加两个新属性,一个用于保存 Sails“模型”的名称,另一个用于保存 Web 套接字。接下来我们修改sync
函数,如果你熟悉Backbone,那么你就会知道,当你调用fetch
等函数时,这个函数就是与服务器接口的函数。通常,它会触发 Ajax 请求,但我们将对其进行自定义以进行套接字通信。
现在,我们没有使用 sync
函数提供的大部分功能,主要是因为我们没有添加用户更新或删除消息的功能,但为了完整起见,我将它们包含在函数定义。
我们来看看sync
函数的第一部分:
var where = {}; if (options.where) { where = { where: options.where } }
此代码首先检查是否发送了任何“where
”子句,这将允许您执行以下操作: messages.fetch({ where : { id: 4 } });
仅获取其中的行id 等于 4。
之后,我们有一些代码来确保已设置 'sailsCollection
' 属性,否则我们会记录一条错误消息。然后,我们创建一个新的套接字并连接到服务器,通过 on('connect')
事件监听连接。
连接后,我们请求指定的“sailsCollection
”索引以拉入当前模型列表。当它接收到数据时,我们使用集合的 set
函数来初始设置模型。
好吧,到目前为止,我们已经有了相当于标准 fetch
命令的命令。下一个代码块是推送通知发生的地方:
this.socket.on("message", _.bind(function(msg){ var m = msg.uri.split("/").pop(); if (m === "create") { this.add(msg.data); } else if (m === "update") { this.get(msg.data.id).set(msg.data); } else if (m === "destroy") { this.remove(this.get(msg.data.id)); } }, this));
现在正在执行的操作(无论是创建、更新还是销毁消息)都可以在实际的 msg
内部找到,然后该操作又在 uri
内部。为了获取操作,我们用正斜杠(“/”)分割 URI,并使用 pop
函数仅获取最后一段。然后,我们尝试将其与 create
、update
或 destroy
三个可能的操作相匹配。
剩下的就是标准的Backbone,我们可以添加、编辑或删除指定的模型。随着我们的新类即将完成,剩下要做的就是更改当前的 MessageCollection
。它需要扩展我们的新集合,而不是扩展 Backbone 集合,如下所示:
var MessageCollection = SailsCollection.extend({ sailsCollection: 'messages', model: MessageModel });
除了扩展我们的新集合之外,我们还将进行另一项更改,以便我们现在设置 sailsCollection 属性,而不是设置 URL 属性。这就是全部内容。在两个不同的浏览器(例如 Chrome 和 Safari)中打开应用程序并注册两个单独的用户。您应该看到从任一浏览器发布的消息都会立即显示在另一个浏览器上,无需轮询,没有麻烦。
Sails 是在杂乱的框架中呼吸的新鲜空气。它在门口检查自己的自我,并尽其所能帮助开发商而不是品牌。我一直在与 Sails 开发人员聊天,我可以告诉您,还有更多令人惊叹的作品正在开发中,看看这个框架的发展方向将会很有趣。
总之,您已经了解了如何在 Sails 中设置、使用和保护数据,以及如何将其与流行的 Backbone 库连接。
与往常一样,如果您有任何意见,请随时在下面留言,或加入我们的 Nettuts+ IRC 频道(freenode 上的“#nettuts”)。感谢您的阅读。
以上是使用Sails.js處理數據的詳細內容。更多資訊請關注PHP中文網其他相關文章!