• CMS:文章管理之视图(4)


    现在来完成分类的编辑操作。原来是想用模型加载数据的,但现在想想,用表单加载会方便些。

    切换到文章管理的控制器,添加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

  • 相关阅读:
    基于centos的freeradius高可用lvs(UDP)
    sql server 2012的AlwaysOn高可用
    python基础题型一
    用户访一个APP或者网页流程示意图
    DNS解析流程
    crontab的定时任务实例
    Xcode设置
    Nvidia Nsight + .NET
    C++ Pointer-to-Member Selector
    C++11
  • 原文地址:https://www.cnblogs.com/hainange/p/6334225.html
Copyright © 2020-2023  润新知