【译】MVC3 20个秘方-(14)使用Ajax 提交 Form表单


======================================================
注:本文源代码点此下载
======================================================

问题

你有一个网页,列出重要的信息明细,你要允许用户迅速、轻松提交一个表单,无需重新加载整个页面,失去自己在网站上的位置。

解决方案

使用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^)/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值