======================================================
注:本文源代码点此下载
======================================================
问题
你有一个网页,列出重要的信息明细,你要允许用户迅速、轻松提交一个表单,无需重新加载整个页面,失去自己在网站上的位置。
解决方案
使用ajaxhelper,创建一个新的form,用新提交的内容自动更新现有的内容。
讨论
下边的例子把以前的秘方放在一起,向人们展示如何让用户提交一本书的评论,而不重定向到另一个页面去看那些评论以及自己提交的评论。
首先,我们需要创建一个新的model,用于存储对书的评论。在model文件夹,右键->添加->class,命名为:bookcomment.cs。这个模型将用于存储对书的评论。代码如下:
using system;
using system.collections.generic;
using system.componentmodel.dataannotations;
using system.linq;
using system.web;
namespace mvcapplication.models
{
public class bookcomment
{
public int id { get; set; }
[required]
public string comment { get; set; }
public datetime created { get; set; }
public int bookid { get; set; }
public virtual book book { get; set; }
}
}
下一步,必须更新先前创建的bookdbcontext,去对这个表添加一个引用。先前的这个类是创建在原始的bookmodel上。因此专门创建一个新的文件来存储这个类是明智的选择。因为它将在您的项目中和未来的表一起继续成长。右键点击models文件夹。再次,选择添加→类。这个类的名称将bookdbcontext:
(译者:不要忘记删除你在book model里的bookdbcontext哦!)
using system;
using system.collections.generic;
using system.data.entity;
using system.linq;
using system.web;
namespace mvcapplication.models
{
public class bookdbcontext : dbcontext
{
public dbset books { get; set; }
public dbset bookcomments { get; set; }
}
}
下面,重新build你的解决方案,在下边的步骤里你就可以找到我们新创建的model了。
我们要创建一个新的controller去实现 评论列表并且有能力去管理它们。选择controller文件夹,单击“添加”→“控制器,命名为:bookcommentscontroller.cs。为了是手工工作最小化。我们将使用entity framework 脚手架创建controller。对于data context class,选择刚才创建的bookdbcontext。(译者:modle class 选择:bookcomment (mvcapplication.models))。点击添加。当你再次运行应用程序时,你将接收到一个错误指示出:bookdbcontext已经改变了。为了解决这个问题,你必须为dbcontext创建一个initializer(初始化器)。因为这不是一个生产环境的应用程序,初始化器将删除和重新创建数据库。为了实现这个,右击models文件夹。选择添加->class ,命名为bookinitializer,代码如下:
using system;
using system.collections.generic;
using system.data.entity;
using system.linq;
using system.web;
namespace mvcapplication.models
{
public class bookinitializer : dropcreatedatabaseifmodelchanges
{
}
}
接下来global.asax.cs要被更新,在application_start中去调用bookinitializer,更新application_start方法如下:
protected void application_start()
{
database.setinitializer(new bookinitializer());
arearegistration.registerallareas();
registerglobalfilters(globalfilters.filters);
registerroutes(routetable.routes);
}
配置工作完成了,现在我们要做的就是允许用户通过ajax提交一个评论。我们将从book/details view 开始,因为展现评论的大多数逻辑都在这里。(译者:由于原书中引用代码较多,我只在这指出我们更改的代码)。代码如下:
@model mvcapplication.models.book
@{
viewbag.title = "details";
}
details
book
class="display-label">
title
class="display-field">
@html.displayfor(model => model.title)
class="display-label">
isbn
class="display-field">
@html.displayfor(model => model.isbn)
class="display-label">
summary
class="display-field">
@html.displayfor(model => model.summary)
class="display-label">
author
class="display-field">
@html.displayfor(model => model.author)
class="display-label">
thumbnail
class="display-field">
@html.displayfor(model => model.thumbnail)
class="display-label">
price
class="display-field">
@html.displayfor(model => model.price)
class="display-label">
published
class="display-field">
@html.displayfor(model => model.published)
comments
"comments">
@{html.renderaction("index", "bookcomments",new { bookid = model.id });}
@html.actionlink("edit", "edit", new { id = model.id }) |
@html.actionlink("back to list", "index")
在上边代码中添加了一个新的,它里边又包含了一个
,div的id是” comments”,在这个div中有一个html.renderaction(),它可以通过传递一个bookid参数到bookcomment controller的index action。
接下来,我们需要更新bookcomments/index view。在下边的例子里,create newlink被更新成,通过ajax替代重定向去展示form。也会移除一些links,因为我们只需要添加的能力,不需要去管理这些评论。代码如下:
@model ienumerable
@{
viewbag.title = "index";
}
index
@ajax.actionlink("create new", "create", new
{
bookid = viewbag.bookid
},
new ajaxoptions { updatetargetid = "addcomment" })
"addcomment">
comment
created
@foreach (var item in model)
{
@html.displayfor(modelitem => item.comment)
@html.displayfor(modelitem => item.created)
@html.displayfor(modelitem => item.book.title)
}
最后注意,需要改变的是自动生成的bookcomments/create view。将使用ajax.beginform 去替换默认的html.beginform。另外一件事是告诉当ajax提交完成时,让form来调用一个javascript:函数reloadcomments()。此函数使用jquery的ajax请求来检索更新的评论列表。也要创建一个带bookid的hidden field去替换自动创建的下拉列表。
代码如下:
@model mvcapplication.models.bookcomment
@{
viewbag.title = "create";
}
create
@using (ajax.beginform(new ajaxoptions
{
oncomplete = "reloadcomments()"
}))
{
@html.hidden("bookid", (int)viewbag.bookid);
@html.validationsummary(true)
bookcomment
class="editor-label">
@html.labelfor(model => model.comment)
class="editor-field">
@html.editorfor(model => model.comment)
@html.validationmessagefor(model => model.comment)
"submit" value="create" />
}
为了完成这个例子,我们还需要在bookcommentscontroller更新一些代码:
(译者:作者为嘛总是说最后一步,都多少个最后一步了,别急,马上就完成了 )
using system;
using system.collections.generic;
using system.data;
using system.data.entity;
using system.linq;
using system.web;
using system.web.mvc;
using mvcapplication.models;
namespace mvcapplication.controllers
{
public class bookcommentscontroller : controller
{
private bookdbcontext db = new bookdbcontext();
//
// get: /bookcomments/
public actionresult index(int bookid)
{
viewbag.bookid = bookid;
var bookcomments = db.bookcomments.include(
b => b.book).where(b => b.bookid == bookid);
return partialview(bookcomments.tolist());
}
//
// get: /bookcomments/create
public actionresult create(int bookid)
{
viewbag.bookid = bookid;
return partialview();
}
//
// post: /bookcomments/create
[httppost]
public actionresult create(bookcomment bookcomment)
{
if (modelstate.isvalid)
{
bookcomment.created = datetime.now;
db.bookcomments.add(bookcomment);
db.savechanges();
}
viewbag.bookid = bookcomment.bookid;
return partialview(bookcomment);
}
protected override void dispose(bool disposing)
{
db.dispose();
base.dispose(disposing);
}
}
}
在上面的例子中,index action已更新,接受整数的参数bookid。这被设置到viewbag。另一个重要变化是,返回一个partial view 替代 返回完整的view(阻止完整的layout显示)。如果你还记得在前面的例子,我们重用了相同的view执行ajax请求,并在视图中检查,看它是否是一个ajax请求去禁用layout。因为这个view是只通过ajax显示,更新controller去返回一个partial view是简单的。
最后,create action也被更新。基本的create action就像index action一样 接收一个bookid,并返回一个partial view。第二,create函action已被更新去设置评论的创建日期。如果有错误,返回一个partial view。edit,details和delete action已经被移除了,因为没用到他们。这些view也可以删除,因为他们也没有被使用。
现在,当用户浏览一本书的细节,他们可以看到全部评论
已发布的,如果他们想添加自己的意见,他们可以看到已经评论的列表。如果他们想添加自己的内容,他们可以点击create new link,输入他们的内容,提交,并且自动的看到他们刚提交的内容而不需要离开book详细页。
绿色通道:好文要顶关注我收藏该文与我联系
======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/