現在來完成分類的編輯操作。原來是想用模型加載數據的,但現在想想,用表單加載會方便些。
切換到文章管理的控制器,添加onCategoryEdit方法,利用表單來加載數據,代碼如下:
onCategoryEdit:function () {
var me = this,
tree =me.view.down("treepanel"),
rs =tree.getSelectionModel().getSelection();
if (rs.length > 0) {
rs = rs[0];
if (rs.data.id > 10000) {
var win =SimpleCMS.view.Content.CategoryEdit;
win.form.getForm().url ="/Category/Edit";
win.setTitle("編輯文章類別");
win.form.load({
url:"Category/Details",
params: { id: rs.data.id },
success: function (form,action) {
this.show();
},
failure:SimpleCMS.FormSubmitFailure,
scope: win
});
} else {
Ext.Msg.alert("信息", "類別“" + rs.data.text + "”不允許編輯。");
}
}
},
分
類id大于10000的才是可以編輯的分類,因而這里要加個判斷。設置好分類編輯窗口的的提交地址和標題后,就調用load方法為表單加載數據了。如果成
功,就顯示窗口。這里要注意作用域的設置,在這里把作用域設置為win了,這樣,在success方法內,this指針就指向窗口了。
現在切換到Category控制器,完成Details方法。根據書12.5.2節的示例可以知道,在data內返回一個JSON對象就可以了,對象中的關鍵字就是表單中字段的名字,這相當簡單,代碼如下:
[AjaxAuthorize(Roles= "普通用戶,系統管理員")]
publicJObject Details()
{
int id=0;
int.TryParse(Request["id"],outid);
try
{
var q = dc.T_Category.SingleOrDefault(m=> m.CategoryId == id);
if (q == null)
{
returnMyFunction.WriteJObjectResult(false, 0, "分類已被刪除或不存在。", null);
}
else
{
return new JObject(
newJProperty("success",true),
new JProperty("data",
new JObject(
newJProperty("CategoryId",q.CategoryId),
newJProperty("Content",q.Content),
newJProperty("Image",q.Image),
newJProperty("Title",q.Title),
newJProperty("SortOrder",q.SortOrder),
newJProperty("ParentId",q.ParentId==null ? -1 : q.ParentId)
)
)
);
}
}
catch (Exception e)
{
returnMyFunction.WriteJObjectResult(false, 0, e.Message, null);
}
}
這里要注意的是ParentId,為null時,要設置為-1,這樣才能對應上是根節點。
現
在還不能測試,因為編輯按鈕現在還是禁用狀態,因而,要監聽分類樹的selectionchange事件,當有選擇了節點且節點id大于10000時啟用
編輯和刪除按鈕。切換到文章管理的控制器,先在me.control語句上添加綁定selectionchange的語句,代碼如下:
me.view.down("treepanel").on("selectionchange",me.onTreeSelect, me);
然后編寫onTreeSelect方法,這里要注意setDisabled的賦值,要把id的值考慮進去,代碼如下:
onTreeSelect:function (model, sels) {
var me = this,
id = 0;
if (sels.length > 0) {
id = sels[0].data.id;
}
me.getCategoryEdit().setDisabled(sels.length == 0 || id <= 10000);
me.getCategoryDelete().setDisabled(sels.length== 0 || id <= 10000);
}
這里,如果存在選擇,則把id值取出來,然后在setDisabled方法內,如果選擇記錄的長度等于0,說明要禁用按鈕,又或者id值小于10000,也要禁用按鈕。
好了,現在可以單擊編輯按鈕對分類進行編輯了。
余下的就是完成編輯操作的后臺代碼了,這個與Add方法區別不大,具體代碼如下:
[HttpPost]
[AjaxAuthorize(Roles= "普通用戶,系統管理員")]
publicJObject Edit(CategoryModel model)
{
bool success = false;
JObject errors = new JObject();
if (ModelState.IsValid)
{
try
{
var q =dc.T_Category.SingleOrDefault(m => m.CategoryId == model.CategoryId);
if (q == null)
{
returnMyFunction.WriteJObjectResult(false, 0, "要修改的記錄已被刪除或不存在。", null);
}
else
{
string old_fullpath =q.FullPath;
q.Content = model.Content;
q.Title = model.Title;
q.SortOrder = model.SortOrder;
if (model.ParentId>10000& dc.T_Category.Select(m =>m.CategoryId).Contains(model.ParentId))
{
q.ParentId =model.ParentId;
}
else
{
q.ParentId = null;
}
dc.SaveChanges();
success = true;
returnMyFunction.WriteJObjectResult(true, 0, "", new JArray(
new JObject(
newJProperty("id", q.CategoryId),
newJProperty("text", q.Title),
newJProperty("parentId", q.ParentId),
newJProperty("fullpath", q.ParentId == null ? "" :q.Parent.FullPath)
)
));
}
}
catch (Exception e)
{
returnMyFunction.WriteJObjectResult(false, 0, e.Message, null);
}
}
else
{
MyFunction.ModelStateToJObject(ModelState, errors);
}
returnMyFunction.WriteJObjectResult(success, errors);
}
這里要注意的是,如果父id不大于10000,或在分類數據庫中不包含該id,就要把父id設置為null。
注意:在數據庫T_Category表的trg_CategoryUpdate觸發器中有個錯誤,需要把開頭的“SET NOCOUNT ON;”屏蔽掉才能正常更新fullpath和HierarchyLevel。
至此,編輯功能就完成了。下面繼續完成刪除功能,這與刪除文件目錄的代碼沒太大區別。切換到文章管理的控制器,完成onCategoryDelete方法,代碼如下:
onCategoryDelete:function () {
var me = this,
tree =me.view.down("treepanel"),
rs =tree.getSelectionModel().getSelection();
if (rs.length > 0) {
rs = rs[0];
if (rs.data.id <= 10000) {
Ext.Msg.alert("刪除類別", "類別“" + rs.data.text + "”不允許刪除!");
return;
}
var content = "確定刪除類別“" + rs.data.text + "”?<br/><p
style='color:red'>注意:該類別下子類將被全部刪除,而該類別及其子類的文章會被移動到未分類中。</p>";
Ext.Msg.confirm("刪除類別", content, function (btn) {
if (btn == "yes") {
var rs =this.getSelectionModel().getSelection();
if (rs.length > 0) {
rs = rs[0];
rs.remove();
this.store.sync({
success: function (e,opt) {
var me = this;
me.store.commitChanges();
me.view.select(0);
me.view.focus(false);
},
failure: function(e,opt) {
var me = this;
me.store.rejectChanges()
Ext.Msg.alert("發生錯誤",e.exceptions[0].error);
},
scope: tree
});
}
}
}, tree)
}
},
現
在,切換到Category控制器,完成Delete方法。在方法內,先要通過fullpath,一次過把所有子類搜索出來,設置其state值為1。然
后把它們包含的文章找出來,設置這些文章的CategoryId值為10000。最后把提交的數據完整返回就行了。具體代碼如下:
[AjaxAuthorize(Roles= "普通用戶,系統管理員")]
publicJObject Delete()
{
bool success = false;
string msg = "";
JArray ja = null;
try
{
string data = Request["data"]?? "";
if (string.IsNullOrEmpty(data))
{
msg = "錯誤的提交數據。";
}
else
{
ja = JArray.Parse(data);
if (ja.Count > 0)
{
JObject jo = (JObject)ja[0];
var q =dc.T_Category.SingleOrDefault(m => m.CategoryId == (int)jo["id"]);
if (q != null)
{
q.State = 1;
var sub = dc.T_Category.Where(m =>m.FullPath.StartsWith(q.FullPath));
foreach (var c in sub)
{
c.State = 1;
}
var content =dc.T_Content.Where(m => sub.Select(n =>n.CategoryId).Contains(m.CategoryId));
foreach (var c in content)
{
c.CategoryId = 10000;
}
dc.SaveChanges();
success = true;
}
else
{
msg = "該類別已被刪除或不存在。";
}
}
else
{
msg = "錯誤的提交數據。";
}
}
}
catch (Exception e)
{
msg = e.Message;
}
returnHelper.MyFunction.WriteJObjectResult(success, 0, msg, ja);
}
除了處理數據部分,整個處理流程基本是一樣的,都是先從data中取得數據,轉換,然后從數據庫獲得數據處理。
余下的小問題是讓樹顯示時選擇一個默認節點,而這個要用到《解決Ext JS 4.1版本Tree在刷新時選擇第一行的問題》中的解決辦法,具體代碼如下:
me.view.down("treepanel").getView().on("refresh",function () {
var tree =this.view.down("treepanel");
var node = tree.getRootNode().firstChild;
if (node) {
tree.getView().select(node);
}
}, me);
至此,文章分類的操作就完成了。下文繼續完成文章管理的操作。
源代碼:http://vdisk.weibo.com/s/iflJg