使用 backbone.js的CRUD操作

分享于 

25分钟阅读

Web开发

  繁體 雙語

介绍

学习 backbone.js 用于基本创建。读取。更新和 delete 操作。 我们将创建一个基本应用程序,它将帮助我们了解如何使用 backbone.js. 编写代码

什么是 Backbone.js

当我们使用javascript应用程序时,我们往往会付出大量努力构造代码,并将正确的peice放在正确的位置。 它实际上可能是可以维护的或者不可扩展的。 来自 Backbone 官方网站-

创建JavaScript应用程序最容易被混乱的jQuery选择器和回调,所有的试图在 HTML UI。JavaScript逻辑和数据库之间同步。 对于富客户端应用程序来说,更加结构化的方法通常是有用的。

现在出现了 backbone.js,它是一个非常轻松的框架,允许你将应用程序结构化为 MV*。 MV代表基本模型和我们在一般术语中所具有的观点。 但是重要的是 *.,我不是开发人员 behind Backbone,因这里很难假定它紧密地适合MVC框架。 我假设它是 ,这样可以让你通过标签url保存你的javascript应用程序的状态。 Stackoverflow的详细信息

例子

我的第一个例子就是 Gmail。 下载大量数据的地方,你登录。 然后事情就变得简单而简单了,background 进程也会。 没有一个页面刷新发生。 Awesome !

便笺

现在我将忽略已经备份的代码。 假设我们已经准备好了 Create/Read/Update/Delete.的api

本文中,我在CRUD操作和 toastr 中使用了 ASP.NET的MVC 我是这个lib的超级粉丝,真是太棒了。

我们要做

我们将尝试创建允许创建用户。显示用户列表。编辑特定用户和删除特定用户的应用程序。

.首先搭建处理查询的环境

让我们开始:

  • 创建一个新的ASP.NET MVC项目。 ( 比如。UserManagement )
  • 选择互联网作为你的模板。
  • 默认情况下不存在 Backbone.js。 所以我们需要右键点击引用并选择管理Nuget软件包并搜索 Backbone。
  • 从软件包列表中安装 backbone.js。
  • 转到 BundleConfig.cs 并添加一个新包并引用 _Layout.cshtml,或者在中添加它并在现有包中添加 backbone.js,这正是在 _layout.cshtml 中引用的。

添加新分发包时:


public static void RegisterBundles(BundleCollection bundles)


{


 // existing code



 bundles.Add(new ScriptBundle("~/bundles/backbone").Include(


 "~/Scripts/underscore.js",


 "~/Scripts/backbone.js"));


 // existing code


}



运行应用程序以检查是否在控制台中引发了任何错误。

设置用户模型( 类)

完成 上面 步骤之后,让我们从创建用户管理应用程序的新模型类开始。


public class User


{


 public int Id { get; set; }


 public string FirstName { get; set; }


 public string LastName { get; set; }


 public int Age { get; set; }


 public string Email { get; set; }


 public string Phone { get; set; }


}



假设 上面 类,我们将继续进行客户端脚本编写。 你可以创建你的CRUD。

显示用户列表

创建路由


var Router = Backbone.Router.extend({


 routes: {


 '': 'home',//Default route, when no hash tag is available


 'create': 'create',// Create User, when user clicks on Create button


 'edit/:id': 'edit'


 }


});



现在,我们为用户的Listing/Edit/Create 创建路由。 当我们的网址为:





http://localhost/#



我们将显示用户名单。





http://localhost/#create



我们将显示用户详细信息屏幕,用于创建用户 换句话说,我们需要显示用户的创建页面。





http://localhost/#edit



我们将显示带有填充数据的用户详细信息屏幕,这些数据将用于编辑/更新用户。

定义路由





var route = new Router();



// When hash tag has localhost# register the below route


route.on('route:home', function () {



 // Todo: code to render create page


 console.log("Display Create Page");


});



// When hash tag has localhost#create register the below route


route.on('route:create', function () {



 // Todo: code to render create page


 console.log("Display Create Page");


});



//When hash tag has localhost#edit/1 register the below route


route.on('route:edit', function () {



 // Todo: code to render edit page and render user details


 console.log("Display Edit Page");


});



现在,我们将路由定义为 上面,它将在url中的标签变化时触发相应的路由定义。 我们很快就会回到这个部分。

运行应用程序以检查是否在控制台中引发了任何错误。 将url更改为/# 或者/#create or/#edit/1, 你应该看到打印的相应控制台语句。

创建模型

的官方说法是:

模型是任何JavaScript应用程序的核心,包含交互数据以及围绕它的大部分逻辑: 转换。验证。计算属性和访问控制。 使用特定领域的方法扩展 Backbone.Model,模型提供了一组基本的功能来管理变更。

所以,我们不浪费很多时间,让我们为我们的Backbone 创建一个用户模型。


var userModel = Backbone.Model.extend({


 defaults: {


 Id: null,


 FirstName: null,


 LastName: null,


 Age: null,


 Email: null,


 Phone: null


 },


 initialize: function () {


 // Do stuff's which you want at the time of model creation


 }


 });



创建集合

的官方说法是:

集合是有序的模型集。 如果你的"更改"事件被修改,侦听"添加"和"移除"事件,以及从服务器获取集合,并使用完整的Underscore.js 方法集合,你可以绑定事件。

在 Collection 中,任何在模型中触发的事件也将直接在 Collection 上触发,以便于方便。 这样可以侦听 Collection 中任何模型中特定属性的更改,例如: documents.on("change:selected",. .. )

Backbone Collection 是 Collection的,当然它有更多的特性。 它拥有超过1 的下划线方法,支持它并允许你在修改或者更改内容时对它们进行监视并执行必要操作。 同时,它支持rest式的api。 太棒了 !


var listOfUsers = Backbone.Collection.extend({


 model: userModel,


 url: '/api/User'


});



简单和甜心的代码。我们提供我们以前创建的模型和默认 API,可以返回 <用户>。 你甚至可以尝试硬编码数据,以防你觉得懒惰创建后台。 一切都正常。

创建视图

的官方说法是:

对于你的HTML或者CSS来说,Backbone 视图比代码更为规范;它们不确定任何关于你的HTML或者CSS的内容,并且可以使用任何JavaScript模板库。 通常的想法是将接口组织到逻辑视图,模型支持,每个模型都可以在模型更改时独立更新。 而不是挖掘到JSON对象,在DOM中查找元素并手动更新 HTML,可以将视图函数呈现到"模型的更改"中。

良好的声音和信息。更详细。

在我们跳转creting视图之前,让我们先决定我们的el元素。 "el"属性引用在浏览器中创建的DOM对象。 每个 backbone.js 视图都有一个"el"属性,如果没有定义,backbone.js 将构造它自己的一个空的div元素。

转到要呈现用户列表页面的页面,并添加一个div标记,指定类 NAME 或者 id。 在我的示例中,删除了主目录/索引。cshtml代码并添加了 below 行:





@{


 ViewBag.Title = "Home Page";


}



<div class="user-management"></div>



我们已经把元素设置好了。 让我们来创建一个视图来呈现数据。


var listOfUsersView = Backbone.View.extend({


 el: '.user-management',// The element we defined in HTML


 render: function () {


 var self = this;// Saving the scope object


 var _userList = new listOfUsers();


 _userList.fetch({


 success: function (data) {


 


 var _userTemplate = _.template($('#user-list-template').html(), { users: data.models });


 self.$el.html(_userTemplate);


 }


 });


 }


});



我在做的是,我创建了一个 Backbone 视图,它具有一个'el'属性,它将保持创建的DOM对象的引用。 其次,"渲染( )"函数会使用jQuery将我们的模板加载到"视野"属性。 这里方法负责获取数据并使用从服务器( render方法不应该有从服务器获取数据的逻辑,我们有方法来重构它,现在我们可以使用它) 获取的数据创建模板。 现在问题是:





_.template($('#user-list-template').html(), { users: data.models });



这是 backbone.js 依赖于 Underscore.js,,它包含自己的模板解决方案。 将JavaScript模板编译为可以计算为呈现的函数。 用于从JSON数据源呈现复杂的HTML位。 阅读有关undersore模板的更多信息。

创建模板

现在创建一个模板将是直接的,如果你使用to或者 Angular,那么你将能够与它相关联。 以防你没有。 不用担心。看看这个模板:


<script type="text/template" id="user-list-template">


 <h3>Following are the user's:</h3>


 <form class="list-group-form">


 <a href="/#create" class="btn btn-default">Create User</a>


 <table class="table striped">


 <thead>


 <tr>


 <th></th>


 <th>Id</th>


 <th>FirstName</th>


 <th>LastName</th>


 <th>Age</th>


 <th>Actions</th>


 </tr>


 </thead>


 <% _.each(users,function(user){%>


 <tr>


 <td>


 <input type="checkbox" /></td>


 <td><%= user.get('Id')%></td>


 <td><%= user.get('FirstName')%></td>


 <td><%= user.get('LastName')%></td>


 <td><%= user.get('Age')%></td>


 <td>


 <a href="/#edit/<%= user.get('Id')%>" class="btn btn-primary">Edit</a></td>


 </tr>


 <%});%>


 </table>


 </form>


</script>



下划线是模板 <脚本> 标记带有"文本/模板",它实际上阻止浏览器在第一次拍摄时呈现它。 浏览器可以理解的不是脚本,因此浏览器只会忽略它。 你可以在这里放置任何可以用作模板的东西。 你可以使用许多其他的库,如车把/mustache 等。


<script type="text/template" id="user-list-template">



</script>



创建一个用户模型,然后创建它的用户 Collection。 然后我们创建了一个视图,它创建一个用户Collecton的对象并激发一个获取请求。 返回数据的API时,我们将获取模板并将数据绑定到它。 finally,显示它。

最后,我们需要从/# 路由( 我们的缺省路线) 调用我们的render方法。 让我们回到我们的位置吧





// When hash tag has localhost# register the below route


route.on('route:home', function () {



 // Todo: code to render create page


 console.log("Display Create Page");


});



现在我们要做的是,调用我们的视图方法呈现。


// When hash tag has localhost# register the below route


route.on('route:home', function () {


 var objList = new listOfUsersView();


 objList.render();


});



运行应用程序以检查是否在控制台中引发了任何错误。 如果一切正常,你应该能够看到来自数据库的用户列表。

注意:如果没有打开网络选项卡,并检查你的R 获得的响应。 检查api返回的字段,并使用模板中定义的内容来定义属性。

创建用户

现在,当我们全部设置为显示用户的列表时,让我们实际创建一个用户并更新数据库。 返回列表应用程序并检查用户是否已经创建或者现在。

当你点击链接创建用户时,你会看到/#create获得的url和控制台将给你回复"显示创建页面"。 所以我们需要在那里开始写代码。 之前我们需要一个创建视图,它负责显示我们的用户模型。

创建模板和基本视图

让我们从创建用户视图开始。 我们将在创建和更新时使用相同的视图。





var specificUserView = Backbone.View.extend({


 el: '.user-management',// The element we defined in HTML


 render: function() {



 }


 });



好了,现在 !

我们不要直接跳到表单域,我想做的就是创建一个simpe文本的模板。 当用户点击创建用户超链接时,我们会显示。


<script type="text/template" id="user-detail-template">


 <h3>User Details:</h3>


 @* Todo: Add the form tag and more *@


</script>



我想呈现模板,看看我点击创建用户超链接时会发生什么。





var specificUserView = Backbone.View.extend({


 el: '.user-management',// The element we defined in HTML


 render: function() {


 var _userDetailTemplate = _.template($('#user-detail-template').html());


 this.$el.html(_userDetailTemplate);


 }


});




现在,我只是在渲染模板,而不做任何其他事情。 当url更改为/#create时调用这里视图。 因这里,我们回到我们定义创建路线的地方,我们调用specificUserView的渲染方法。


// When hash tag has localhost#create register the below route


route.on('route:create', function () {


 var _objUser = new specificUserView();


 _objUser.render();


});



运行应用程序以检查是否在控制台中引发了任何错误。 如果一切顺利,你应该能看到我们的文字印刷。 让我们添加表单元素并创建我们的表单,它将接受所需的属性。 当我们添加输入字段时,表单看起来类似于:


<script type="text/template" id="user-detail-template">


 <h3>User Details</h3>


 <table>


 <tr>


 <td>First Name</td>


 <td>:</td>


 <td>


 <input type="text" class="first-name" /></td>


 </tr>


 <tr>


 <td>Last Name</td>


 <td>:</td>


 <td>


 <input type="text" class="last-name" /></td>


 </tr>


 <tr>


 <td>Age</td>


 <td>:</td>


 <td>


 <input type="text" class="age" /></td>


 </tr>


 </table>



 <input type="button" value="Save" id="saveUserDetails"/>


</script>



创建保存事件

每个 Backbone 视图都允许我们定义事件 对于 e.g.:





var DocumentView = Backbone.View.extend({


 events: {


 "dblclick": "open",


 "click. icon.doc": "select"


 }


});



delegateEvents takes事件: {。"。"。} 声明,用指定的回调方法将指定的事件绑定到指定的DOM元素。

我们需要有一个提交按钮单击。 因此,我们在我们





specificUserView 



如下所示:


var specificUserView = Backbone.View.extend({


 el: '.user-management',// The element we defined in HTML


 events: {


 'click #saveUserDetails': 'saveUserDetails'


 },


 render: function() {


 var _userDetailTemplate = _.template($('#user-detail-template').html());


 this.$el.html(_userDetailTemplate);


 },


 saveUserDetails: function() {


 console.log("Save user details");


 }


});



运行应用程序以检查是否在控制台中引发了任何错误。 点击保存按钮以检查控制台消息是否在F12控制台窗口中显示。

现在,我们需要saveUserDetails方法的工作。 这里方法负责创建具有当前填充属性的模型对象,并将详细信息保存到服务器。

我想让它保持简单:


saveUserDetails: function () {



 // Create a user model to fill the form details


 var model = new userModel({


 id: null,


 FirstName: $('.first-name').val(),


 LastName: $('.last-name').val(),


 Age: $('.age').val()


 });



 model.save({}, {


 success: function () {


 console.log('Data Saved');


 route.navigate('', { trigger: true });// Navigate back to listing page


 }


 });



}



编辑用户

现在,这是最大的挑战。 我们将使用我们的创建表单来显示编辑信息。 因为我们需要对代码做一些修改。

路线


//When hash tag has localhost# register the below route


route.on('route:edit', function (userId) {


 var _objUserEdit = new specificUserView();


 _objUserEdit.render(userId);


});



路由将接受Id作为参数,并将它的传递给render方法。

查看&模板

现在,我们需要更改视图以接受用户Id并获取有关用户Id的数据。 此外,我们需要更新我们的视图,在提供时显示值。 因此,我更改了我的特定用户视图 var specificUserView,如下所示:


render: function (userId) {


 var userDetails=null;


 if (userId) {


 var self = this;



 // User update. We need to fetch user details from server and


 // render the template.


 var _userModel = new userModel({ id: userId });



 _userModel.fetch({


 data: {id:userId},


 success: function (data) {


 var _userDetailTemplate = _.template($('#user-detail-template').html(),


 { user: data });


 self.$el.html(_userDetailTemplate);


 }


 });


 }


 else


 {


 // User is created


 var _userDetailTemplate = _.template($('#user-detail-template').html(),


 { user: null });


 this.$el.html(_userDetailTemplate);


 }



 }



类似地,我们将HTML与模型数据绑定。


<tr>


 <td>First Name</td>


 <td>:</td>


 <td>


 <input type="text" class="first-name" value="<%= user? user.get('FirstName') : '' %>"/></td>


</tr>


<tr>


 <td>Last Name</td>


 <td>:</td>


 <td>


 <input type="text" class="last-name" value="<%= user? user.get('LastName') : '' %>"/></td>


</tr>


<tr>


 <td>Age</td>


 <td>:</td>


 <td>


 <input type="text" class="age" value="<%= user? user.get('Age') : '' %>"/></td>


</tr>



如果你现在可以看到所有输入元素都绑定了值:


user.get('FirstName')



你可以使用 handlebar.js 和其他方法在不同文件中创建模板,而不是像以前那样保存模板文件。 编译prehand或者在运行时编译。 关于车把的更多细节

重构的区域

上面 代码是使用 backbone.js的非常原始的版本。 我们需要对上面提到的代码进行重构。 就像保存用户时一样,我们应该导航回列表页面来显示用户的列表 e.g.


route.navigate('', { trigger: true });



其次重要的是破坏视图





kill: function() {



 // COMPLETELY UNBIND THE VIEW


 this.undelegateEvents();



 this.$el.removeData().unbind(); 



 // Remove view from DOM


 this.remove(); 


 Backbone.View.prototype.remove.call(this);



}



会尝试写更多关于内存泄漏的信息。

改进的反馈和评论

作为第一篇文章,我欢迎你对改进和错误的建议。 我在撰写这个网页时可能会失去耐心,所以请大家放心。


相关文章