4

有没有办法在不使用 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);
}
4

3 回答 3

3

谢谢,经过多次尝试和失败,我终于弄明白了。基本上,代码在回调 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

于 2013-07-23T14:26:13.993 回答
2

感谢您的回复。

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

它被命名为CascadingFromField

于 2014-08-27T23:44:38.770 回答
1

.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 => e.Change("OnParentChanged"))了,因为它会在父级更改时自动更新子级。但是,您确实需要确保传入的 IDFilterChild返回基于父 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();
}
于 2015-02-28T00:35:01.607 回答