【问题标题】:Kendo UI Cascading DropDownList without using CascadeFrom不使用 CascadeFrom 的 Kendo UI Cascading DropDownList
【发布时间】:2013-07-22 21:24:43
【问题描述】:

有没有办法在不使用 CascadeFrom 的情况下拥有两个级联下拉菜单(即手动触发事件)?我不想使用 CascadeFrom 的原因是因为两个模型中的属性名称相同,因此我的父级和子级下拉列表 DataValueField 都设置为 DataValueField("ID"),如下所示。

型号

 class ParentDropdownModel
    {
     public int ID { get; set; }
     public string Name { get; set; }
    }

    class ChildDropdownModel
    {
     public int ID { get; set; }
    public string Name { get; set; }
    }

查看

@(Html.Kendo().DropDownList()
.AutoBind(true)
.Name("ddlParent")        
.DataTextField("Name")
.DataValueField("ID")
.OptionLabel("Select a parent...")
.DataSource(ds => ds.Read(read => read.Action("ReadParent", "Home")))
.Events(e => e.Change("OnParentChanged"))
)

@(Html.Kendo().DropDownList()
.AutoBind(false)
.Name("ddlChild")
.DataSource(ds => ds.Read(read => read.Action("FilterChild", "Home").Data("filterChild")))
.DataTextField("Name")
.DataValueField("ID")
.OptionLabel("Select a child...")
)   

<script type="text/javascript">          
    function OnParentChanged(e)
    {            
        var child = $('#ddlChild').data("kendoDropDownList");           
        child.dataSource.read(filterChild());            
    }
    function filterChild()
    {
        var myid = $("#ddlParent").val();            
        return
        {                
            parentID: $("#ddlParent").val()
        };
    }    
</script>

控制器

public ActionResult FilterChild([DataSourceRequest] DataSourceRequest request, string parentID)
{
    // Here is the Problem: parentID is null at run-time
    return Json(dummyData, JsonRequestBehavior.AllowGet);
}

【问题讨论】:

    标签: kendo-ui kendo-asp.net-mvc


    【解决方案1】:

    谢谢,经过多次尝试和失败,我终于弄明白了。 基本上,代码在回调 FilterChild 服务器方法时为 parentID 传递了 null 值。所有代码都是这样,我只是对 JavaScript 代码进行了一些更改,所以现在它调用服务器端方法并传递 parentID 参数的实际值。
    这是视图的部分代码。

    这可行,但如果有比这更好的方法,请告诉我。我愿意学习。

    查看:

    function OnParentChanged(e)
        {        
             var child = $('#ddlChild').data("kendoDropDownList");     
            child.enable(true);
            var myid = $("#ddlParent").val();
            child.dataSource.read({ parentID: myid });
        }
    
     //IMPORTANT: NO NEED TO CALL filterChild() FUNCTION, 
     //   Just pass JSON key value pair AS ABOVE.
    

    这个解决方案的灵感来自这篇文章 Combobox Cascading need more specific cascadeFrom option

    【讨论】:

      【解决方案2】:

      感谢您的回复。

      我认为此类示例有一个新的配置字段。

      它被命名为CascadingFromField

      【讨论】:

        【解决方案3】:

        如果您在子项中有一个与父项相关的外键,则可以在子项下拉列表中使用.CascadeFrom("ddlParent")

        using System.ComponentModel;
        using System.ComponentModel.DataAnnotations;
        using System.ComponentModel.DataAnnotations.Schema;
        
        class Parent
        {
           public (Parent) 
           {
                Children = new HashSet<Child>();
           }
        
           public int ID { get; set; }
           public string Name { get; set; }
        
           public virtual ICollection<Child> Children { get; set;} // navigation property for MVC
        }
        
        class Child
        {
           public int ID { get; set; }
           public string Name { get; set; }
        
           [Column("ParentID")]
           public int ParentId { get; set; } // this is the 'ID' value of the Parent object
        
           [ForeignKey("ParentId")]
           public virtual Child Child { get; set; } // navigation property for MVC
        }
        
        class MainModel
        {
            [DisplayName("Child")]
            [ColumnName("ChildID")]
            public int ChildId { get; set; }
        
            [ForeignKey("ChildID")]
            public virtual Child Child { get; set; }
        }
        

        这通常是设置数据库关系/导航属性的方式。那么你就不需要.Events(e =&gt; e.Change("OnParentChanged")),因为它会在父级更改时自动更新子级。但是,您确实需要确保传递给FilterChild 的 ID 返回基于父 ID 过滤的子项,但在控制器的该函数中。为避免该 ID 为空,您应该在 ID #1 上将下拉菜单设置为初始值,例如“None”,而不是使用 OptionLabel:

        @model MainModel
        
        <table><tr><td>Parent:</td><td>
        @(Html.Kendo().DropDownListFor(model => model.Child.ParentId)
            .AutoBind(true)
            .Name("ddlParent")        
            .DataTextField("Name")
            .DataValueField("ID")
            .DataSource(ds => ds.Read(read => read.Action("ReadParent", "Home")))
            .Value(Model.Child != null ? Model.Child.ParentId.ToString() : "1")
        )
        </td></tr><tr><td>Child:</td><td>
        @(Html.Kendo().DropDownListFor(model => model.ChildId)
            .AutoBind(false)
            .Name("ddlChild")
            .DataSource(ds => ds.Read(read => read.Action("FilterChild", "Home").Data("filterChild")))
            .DataTextField("Name")
            .DataValueField("ID")
            .CascadeFrom("ddlParent")
            .Value(Model.ChildId != 0 ? Model.ChildId.ToString() : "1")
        )   
        </td></tr></table>
        

        FilterChild 看起来像这样,如果返回时该父级没有子级,您可以将值默认为“无”ID:

        public JsonResult FilterChild(string parentID)
        {
            int parentId = int.Parse(parentID);
            List<Child> data = (List<Child>)GetChildrenForParent(parentId);
            if (data.Count() == 0) {
                Child nullChild = new Child();
                nullChild.Id = 1;
                nullChild.ParentId = parentId;
                nullChild.Name = "None";
                data.Add(nullChild);
            }
            return Json(data, JsonRequestBehavior.AllowGet());
        }
        
        public IList<Child> GetChildrenForParent(int parentId)
        {
            return datacontext.Children.Where(c => c.ParentId == parentId)
                    .OrderBy(c => c.Name)
                    .ToList();
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多