当前位置: 代码迷 >> Web前端 >> ASP.NET Web API & Backbone (二) ―― CRUD
  详细解决方案

ASP.NET Web API & Backbone (二) ―― CRUD

热度:703   发布时间:2013-02-28 11:33:09.0
ASP.NET Web API & Backbone (2) ―― CRUD

本章主要介绍使用Backbone 对 WebAPI 进行CRUD,我们将会操作一个数据集(比如:留言簿里的留言一览)。对于数据集合,Backbone 里有专门的类型―― Backbone.Collection。对于集合的管理,Backbone.Collection 在创建后有 add, remove 事件,子元素的 update 需要自己在 model 上监听 "change" 事件。根据初始化的 Backbone.Collection.url,Collection会自动为子元素分配 url/:id 这样的URL,所以 Model 里应该定义 id 属性。另一方面,服务端的 WebAPI结构也需要符合规范。


整体示意图如下:

这里将一条Comment的View拆分出来,CommentListView 将 fetch 数据再挨个创建出 CommentView 。CommentListView 响应 UI 的删除和添加操作。

CommentView 和 Comment Model:

var CommentModel = Backbone.Model.extend({
	idAttribute: "ID",
	urlRoot: 'api/comments'
});

var CommentView = Backbone.View.extend({
	el: '',
	template: _.template($('#commentTemplate').html()),
	initialize: function () {
		this.model.on('change', this.render, this);
		this.model.on('destroy', this.remove, this);
	},
	render: function() {
		var data = this.model.toJSON();
		this.$el.html(this.template(data));
		return this;
	},
	remove: function() {
		this.$el.remove();
	}
});
注意:delete 按钮按下处理时,需要知道处理的是哪一个 Model,因此在Template 生成时,将 CommentModel 的 ID 属性保存到 HTML 里了。
<script id="commentTemplate" type="text/html">
	<li class="comment">
		<header>
		  <div class="info">
			<img src='<%= GravatarUrl %>' />
			<strong><span><%= Author %></span></strong>
		  </div>
		  <div class="actions">
			<a class="delete" href="#" id='<%= ID %>'>Delete Id: <span><%= ID %></span></a>
		  </div>
		</header>
		<div class="body">
		  <p><%= Text %></p>
		</div>
	</li>
</script>

对于一览的控制:CommentList 则继承于 Backbone.Collection,由 CommentListView 处理 delete 和 submit 按钮事件:
CommentList.model.models 就是 CommentModel 的集合。
var CommentList = Backbone.Collection.extend({
	url: 'api/comments',                
	model: CommentModel
});

var CommentListView = Backbone.View.extend({
	el: 'body',
	initialize: function () {
		this.model.on('reset', this.render, this);
	},
	events : {
		'click .delete': 'delete',
		'click .submit': 'create'
	},
	render: function () {
		var self = this;
		$('#comments').empty();
		_.each(this.model.models, function(mdl) {
			var commentView = new CommentView({model: mdl});
			$('#comments').append(commentView.render().$el);
		});
	},
	delete: function(obj) {
		alert('delete: ' +  $(obj.currentTarget).attr('id'));
		var id = parseInt($(obj.currentTarget).attr('id'), 10);
		var deletedModel = _.find(this.model.models, function(item) {
			return item.get('ID') === id;
		});
		var self = this;
		deletedModel.destroy(
		{
		   success: function() {
			   self.model.remove(deletedModel);
		   },
		   error: self.errorHandle
		});						
	},
	create: function() {
		var metaData = { 
			ID: null, Text: $('#text').val(), 
			Author: $('#author').val(), Email: $('#email').val(), 
			GravatarUrl: '' 
		};
		var comment = new CommentModel(metaData);
		var self = this;
		comment.save(metaData, 
		{
		  success: function(res) {
			console.log(JSON.stringify(res));						
			self.model.add(res);                        
			var view = new CommentView({model: res});
			$('#comments').append(view.render().$el);
		  }, 
		  error: self.errorHandle
	   });
	},
	errorHandle: function(model, xhr, options) {
		var err = $.parseJSON(xhr.responseText);
		alert(err.ExceptionMessage);
	}
});
按照 Backbone 的定义,Model 会从 Collection.url 里“继承” URL,然后加上 id 属性。但是如果新创建的 Model(add 操作),这个新Model对应URL就无法取得了。因此可以看到上面 CommentModel 的代码中加了 urlRoot 属性,保证新建的 Model 也能映射到正确的 URL 上。说到这里,Backbone 和 Knockout  比较起来,需要写更多的代码,但也更加灵活。Backbone 里的 Backbone.sync 封装了 AJAX 的逻辑。而 Knockout 需要自己去调用ajax 了。



  相关解决方案