实现qq邮箱换肤(第二季 )
本文代码要实现的目标:与qq邮箱相同的换肤功能,qq邮箱中设置皮肤的部分使用的iframe,这里使用的是jquery异步换肤。业务逻辑与数据访问层与"第一季"基本相同。
简单流程:
1、从数据库获取风格模版的列表。
2、获取一个用户所选择的风格模版,若该用户从未选择风格模版,那么使用默认选中项
3、用户点击图片即可更改风格模版。
使用的技术:三层架构,mvc,linq,jquery。
下面是效果图:
之前的风格:
选择后的风格:
局部视图(partialView)
代码
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<BL.Style>>" %>
<%
SelectList list=null;
BL.Style currentStyle = ViewData["currentStyle"] as BL.Style;
if (ViewData["styleList"] != null)
{
list = ViewData["styleList"] as SelectList;
}
%>
<%=Html.Hidden("currentStyle", currentStyle.StyleID)%>
<div class="itemcontent-font btnHyperLink" style=" text-align:center; width:50%;" >
<%for (int i = 0; i < Model.Count();i++ )
{
if (Model.ElementAt(i).StyleID == currentStyle.StyleID)
{
%>
<div id="stylePanel<%=Model.ElementAt(i).StyleID %>" class="box selected" >
<img src="<%=Model.ElementAt(i).StylePath%>" onclick = "return submitStyle('<%=Model.ElementAt(i).StyleID%>','<%=Model.ElementAt(i).StyleName%>');"/><br /><%=Model.ElementAt(i).StyleDescription%>
</div>
<%
}
else
{%>
<div id="stylePanel<%=Model.ElementAt(i).StyleID %>" class="box">
<img src="<%=Model.ElementAt(i).StylePath%>" onclick = "return submitStyle('<%=Model.ElementAt(i).StyleID%>','<%=Model.ElementAt(i).StyleName%>');" /><br /><%=Model.ElementAt(i).StyleDescription%>
</div>
<%
}
}
%>
</div>
<br />
<span style=" color:red;">提示:选中后将自动保存。</span>
<%
SelectList list=null;
BL.Style currentStyle = ViewData["currentStyle"] as BL.Style;
if (ViewData["styleList"] != null)
{
list = ViewData["styleList"] as SelectList;
}
%>
<%=Html.Hidden("currentStyle", currentStyle.StyleID)%>
<div class="itemcontent-font btnHyperLink" style=" text-align:center; width:50%;" >
<%for (int i = 0; i < Model.Count();i++ )
{
if (Model.ElementAt(i).StyleID == currentStyle.StyleID)
{
%>
<div id="stylePanel<%=Model.ElementAt(i).StyleID %>" class="box selected" >
<img src="<%=Model.ElementAt(i).StylePath%>" onclick = "return submitStyle('<%=Model.ElementAt(i).StyleID%>','<%=Model.ElementAt(i).StyleName%>');"/><br /><%=Model.ElementAt(i).StyleDescription%>
</div>
<%
}
else
{%>
<div id="stylePanel<%=Model.ElementAt(i).StyleID %>" class="box">
<img src="<%=Model.ElementAt(i).StylePath%>" onclick = "return submitStyle('<%=Model.ElementAt(i).StyleID%>','<%=Model.ElementAt(i).StyleName%>');" /><br /><%=Model.ElementAt(i).StyleDescription%>
</div>
<%
}
}
%>
</div>
<br />
<span style=" color:red;">提示:选中后将自动保存。</span>
点击图片触发的javascript脚本
代码
//提交个人风格模版
//styleID:被选择的样式ID
//styleName:样式表的相对路径
function submitStyle(styleID, styleName) {
var stylePanel = document.getElementById("stylePanel" + styleID);
var hidden = document.getElementById("currentStyle");
if (hidden.value == styleID) {
return;
}
$.get("http://www.cnblogs.com/SiteStyle/SubmitStyle?styleID=" + styleID, function() { showRe(styleID, styleName); });
return false;
}
//styleID:被选择的样式ID
//styleName:样式表的相对路径
function showRe(styleID, styleName) {
var hidden = document.getElementById("currentStyle");
var currentElement = document.getElementById("stylePanel" + hidden.value);
currentElement.className = "box";
var stylePanel = document.getElementById("stylePanel" + styleID);
stylePanel.className = "box selected";
hidden.value = styleID;
var style = document.getElementById("personalStyle");
style.href = styleName;
}
//styleID:被选择的样式ID
//styleName:样式表的相对路径
function submitStyle(styleID, styleName) {
var stylePanel = document.getElementById("stylePanel" + styleID);
var hidden = document.getElementById("currentStyle");
if (hidden.value == styleID) {
return;
}
$.get("http://www.cnblogs.com/SiteStyle/SubmitStyle?styleID=" + styleID, function() { showRe(styleID, styleName); });
return false;
}
//styleID:被选择的样式ID
//styleName:样式表的相对路径
function showRe(styleID, styleName) {
var hidden = document.getElementById("currentStyle");
var currentElement = document.getElementById("stylePanel" + hidden.value);
currentElement.className = "box";
var stylePanel = document.getElementById("stylePanel" + styleID);
stylePanel.className = "box selected";
hidden.value = styleID;
var style = document.getElementById("personalStyle");
style.href = styleName;
}
Controller中的代码:
代码
/// <summary>
/// 可供选择的风格模版列表,用户如选择了风格模版,那么StyleID作为下拉框的被选择项;
/// 如果用户没有选择风格模版,那么选中项默认为StyleID==1的项
/// </summary>
/// <returns></returns>
public ActionResult StyleCanSelected(int typeID)
{
Guid authorGuid = Helpers.Helper.GetVisitor().UserGuid;
//获取样式模版列表
List<BL.Style> styles = obj.GetStylesByType(typeID);
//获取用户选中的样式模版
BL.Style style = obj.GetStyleByUser(authorGuid);
//用户未选择样式模版时,默认StyleID == 1的模版
if (style == null)
{
style = new BL.Style() { StyleID = 1, StylePath = "http://www.cnblogs.com/Content/PersonalFirst/style/1.png" };
}
//用户绑定dropdownlist的数据,styles为业务逻辑的数据,
//StyleID为value字段,StyleDescription为text字段,style.StyleID为选中项的value值
SelectList selectList = new SelectList(styles, "StyleID", "StyleDescription",style.StyleID);
ViewData["styleList"] = selectList;
ViewData["currentStyle"]=style;
return View(styles);
}
/// <summary>
/// 提交用户的选择,保存到数据库
/// </summary>
/// <param name="styleID"></param>
/// <returns></returns>
public ActionResult SubmitStyle(int styleID)
{
Guid authorGuid = Helpers.Helper.GetVisitor().UserGuid;
obj.SetupStyle(authorGuid, styleID);
//刷新设置页面
return RedirectToAction("PersonSetting", "Person", new { ownerGuid = authorGuid });
}
/// 可供选择的风格模版列表,用户如选择了风格模版,那么StyleID作为下拉框的被选择项;
/// 如果用户没有选择风格模版,那么选中项默认为StyleID==1的项
/// </summary>
/// <returns></returns>
public ActionResult StyleCanSelected(int typeID)
{
Guid authorGuid = Helpers.Helper.GetVisitor().UserGuid;
//获取样式模版列表
List<BL.Style> styles = obj.GetStylesByType(typeID);
//获取用户选中的样式模版
BL.Style style = obj.GetStyleByUser(authorGuid);
//用户未选择样式模版时,默认StyleID == 1的模版
if (style == null)
{
style = new BL.Style() { StyleID = 1, StylePath = "http://www.cnblogs.com/Content/PersonalFirst/style/1.png" };
}
//用户绑定dropdownlist的数据,styles为业务逻辑的数据,
//StyleID为value字段,StyleDescription为text字段,style.StyleID为选中项的value值
SelectList selectList = new SelectList(styles, "StyleID", "StyleDescription",style.StyleID);
ViewData["styleList"] = selectList;
ViewData["currentStyle"]=style;
return View(styles);
}
/// <summary>
/// 提交用户的选择,保存到数据库
/// </summary>
/// <param name="styleID"></param>
/// <returns></returns>
public ActionResult SubmitStyle(int styleID)
{
Guid authorGuid = Helpers.Helper.GetVisitor().UserGuid;
obj.SetupStyle(authorGuid, styleID);
//刷新设置页面
return RedirectToAction("PersonSetting", "Person", new { ownerGuid = authorGuid });
}
业务逻辑层(BLL)中代码:
代码
public class CustomStyleBL
{
CustomStyleRep obj = new CustomStyleRep();
/// <summary>
/// 获取一种类型的风格模版列表
/// </summary>
/// <param name="typeID"></param>
/// <returns></returns>
public List<Style> GetStylesByType(int typeID)
{
return obj.GetStylesByType(typeID).ToList();
}
/// <summary>
/// 设置用户风格模版
/// </summary>
/// <param name="userGuid"></param>
/// <param name="styleID"></param>
/// <returns></returns>
public int SetupStyle(Guid userGuid, int styleID)
{
return obj.SetupStyle(userGuid, styleID);
}
/// <summary>
/// 获取一人的风格模版
/// </summary>
/// <param name="userGuid"></param>
/// <returns></returns>
public Style GetStyleByUser(Guid userGuid)
{
return obj.GetStyleByUser(userGuid);
}
}
{
CustomStyleRep obj = new CustomStyleRep();
/// <summary>
/// 获取一种类型的风格模版列表
/// </summary>
/// <param name="typeID"></param>
/// <returns></returns>
public List<Style> GetStylesByType(int typeID)
{
return obj.GetStylesByType(typeID).ToList();
}
/// <summary>
/// 设置用户风格模版
/// </summary>
/// <param name="userGuid"></param>
/// <param name="styleID"></param>
/// <returns></returns>
public int SetupStyle(Guid userGuid, int styleID)
{
return obj.SetupStyle(userGuid, styleID);
}
/// <summary>
/// 获取一人的风格模版
/// </summary>
/// <param name="userGuid"></param>
/// <returns></returns>
public Style GetStyleByUser(Guid userGuid)
{
return obj.GetStyleByUser(userGuid);
}
}
数据访问层(DAL)中代码:
代码
public class CustomStyleRep
{
EschoolBLDataContext db = new EschoolBLDataContext();
/// <summary>
/// 获取指定类别的风格模版
/// </summary>
/// <param name="typeID"></param>
/// <returns></returns>
public IQueryable<Style> GetStylesByType(int typeID)
{
IQueryable<Style> query = db.Style.Where(u => u.TypeID == typeID);
return query;
}
/// <summary>
/// 设置风格模版
/// </summary>
/// <param name="userGuid"></param>
/// <param name="styleID"></param>
/// <returns></returns>
public int SetupStyle(Guid userGuid,int styleID)
{
var userStyle = db.UserStyle.SingleOrDefault(u => u.UserGuid == userGuid);
if (userStyle != null)
{
//更新风格模版
userStyle.Style = db.Style.SingleOrDefault(u => u.StyleID == styleID);
}
else
{
//添加风格模版
userStyle = new UserStyle
{
UserGuid = userGuid,
StyleID = styleID,
ModifyTime = DateTime.Now
};
db.UserStyle.InsertOnSubmit(userStyle);
}
int count = db.GetChangeSet().Inserts.Count + db.GetChangeSet().Updates.Count;
db.SubmitChanges();
return count;
}
/// <summary>
/// 获取用户的风格模版
/// </summary>
/// <param name="userGuid"></param>
/// <returns></returns>
public Style GetStyleByUser(Guid userGuid)
{
var userStyle = db.UserStyle.SingleOrDefault(u => u.UserGuid == userGuid);
if(userStyle!=null)
{
return userStyle.Style;
}else
{
return null;
}
}
}
{
EschoolBLDataContext db = new EschoolBLDataContext();
/// <summary>
/// 获取指定类别的风格模版
/// </summary>
/// <param name="typeID"></param>
/// <returns></returns>
public IQueryable<Style> GetStylesByType(int typeID)
{
IQueryable<Style> query = db.Style.Where(u => u.TypeID == typeID);
return query;
}
/// <summary>
/// 设置风格模版
/// </summary>
/// <param name="userGuid"></param>
/// <param name="styleID"></param>
/// <returns></returns>
public int SetupStyle(Guid userGuid,int styleID)
{
var userStyle = db.UserStyle.SingleOrDefault(u => u.UserGuid == userGuid);
if (userStyle != null)
{
//更新风格模版
userStyle.Style = db.Style.SingleOrDefault(u => u.StyleID == styleID);
}
else
{
//添加风格模版
userStyle = new UserStyle
{
UserGuid = userGuid,
StyleID = styleID,
ModifyTime = DateTime.Now
};
db.UserStyle.InsertOnSubmit(userStyle);
}
int count = db.GetChangeSet().Inserts.Count + db.GetChangeSet().Updates.Count;
db.SubmitChanges();
return count;
}
/// <summary>
/// 获取用户的风格模版
/// </summary>
/// <param name="userGuid"></param>
/// <returns></returns>
public Style GetStyleByUser(Guid userGuid)
{
var userStyle = db.UserStyle.SingleOrDefault(u => u.UserGuid == userGuid);
if(userStyle!=null)
{
return userStyle.Style;
}else
{
return null;
}
}
}
总结:该文中局部视图是通过ajax异步加载的,点击"选择风格"即加载。原想将currentStyleID保存在javascript的变量中,如下所示:
<script type="text/javascript">
var currentStyleID=<%=currentStyle.StyleID %>
</script>
var currentStyleID=<%=currentStyle.StyleID %>
</script>
该代码在异步加载的时候会产生错误,因为用脚本给元素赋值时,值内容不能包含脚本块和脚本引用,例如:
document.getElementById("xxx").innerHTML="<script type='text/javascript'>alert('aaaa')</script>"
这段代码会产生错误,最后只好将currentStyleID保存在隐藏控件中。