Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 从多级动态集合中添加下拉列表_Asp.net Mvc - Fatal编程技术网

Asp.net mvc 从多级动态集合中添加下拉列表

Asp.net mvc 从多级动态集合中添加下拉列表,asp.net-mvc,Asp.net Mvc,我有这些模型 项目视图模型 public class ProjectViewModel { //some properties.. public IList<ScopeOfWorkViewModel> ScopeOfWork { get; set; } } 公共类项目视图模型 { //一些属性。。 公共IList工作范围{get;set;} } 工作视图模型范围 public class ScopeOfWorkViewModel

我有这些模型

项目视图模型

public class ProjectViewModel
    {
        //some properties..

        public IList<ScopeOfWorkViewModel> ScopeOfWork { get; set; }
    }
公共类项目视图模型
{
//一些属性。。
公共IList工作范围{get;set;}
}
工作视图模型范围

public class ScopeOfWorkViewModel
    {
        //some properties
        public IList<MaterialsViewModel> Materials { get; set; }
    }
公共类ScopeOfWorkViewModel
{
//一些性质
公共IList材质{get;set;}
}
材质视图模型

 public class MaterialsViewModel
        {
            public int MaterialId { get; set; }
            [Display(Name = "Material")]
            public string MaterialName { get; set; }
            public int? Quantity { get; set; }
            public double? Cost { get; set; }
            public int? ScopeOfWorkId { get; set; }

            // should be a drop down list and get its data from database
            public IEnumerable<SelectListItem> CategoryList { get; set; }
        }
公共类材质视图模型
{
公共int MaterialId{get;set;}
[显示(Name=“Material”)]
公共字符串MaterialName{get;set;}
公共整数?数量{get;set;}
公共双成本{get;set;}
public int?ScopeOfWorkId{get;set;}
//应该是一个下拉列表,并从数据库获取其数据
公共IEnumerable类别列表{get;set;}
}
类别模型

 public partial class tblCategory
    {
        public tblCategory()
        {
            this.tblMaterials = new HashSet<tblMaterial>();
        }

        public int CategoryId { get; set; }
        public string CategoryName { get; set; }

        public virtual ICollection<tblMaterial> tblMaterials { get; set; }
    }
公共部分类TBL类别
{
公共TBL类别()
{
this.tblMaterials=new HashSet();
}
public int CategoryId{get;set;}
公共字符串CategoryName{get;set;}
公共虚拟ICollection tblMaterials{get;set;}
}
这是我的看法

@model MigratingDB.Models.ProjectViewModel
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal" id="ProjectForm">
        <h4>ProjectViewModel</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        Dynamically add ScopeOfWork and Materials<br />
        <a href="javascript:void(0)" id="addScope">Add Scope of Work</a>
        <div id="scopes">
            <div class="scope">
                <div class="materials">
                    <div class="material">
                    </div>
                </div>
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>


<div id="newScope" style="display:none">
    <div class="scope">
        <h3>Scope</h3>
        <div class="form-group">
            <label for="_#__ScopeOfWorkName" class="control-label col-md-2">Scope Of Work</label>
            <div class="col-md-10">
                <input class="form-control" type="text" id="_#__ScopeOfWorkName" name="ScopeOfWork[#].ScopeOfWorkName" value="">
            </div>
        </div>
        <input type="hidden" class="scopeindex" name="ScopeOfWork.Index" value="#" />

        <div class="materials">
            <h4>Material</h4>
            <a href="javascript:void(0)" class="addmaterial">Add Material</a>
        </div>
    </div>
</div>

<div id="newMaterial" style="display:none">
    <div class="form-group">
        <label for="_#__Materials_%__MaterialName" class="control-label col-md-2">Material</label>
        <div class="col-md-2">
            <input class="form-control" type="text" id="_#__Materials_%__MaterialName" name="ScopeOfWork[#].Materials[%].MaterialName" value="">
        </div>
    </div>

    <div class="form-group">
        <label for="_#__Materials_%__Quantity" class="control-label col-md-2">Quantity</label>
        <div class="col-md-1">
            <input class="form-control" type="text" id="_#__Materials_%__Quantity" name="ScopeOfWork[#].Materials[%].Quantity" value="">
        </div>
    </div>

    <div class="form-group">
        <label for="_#__Materials_%__Cost" class="control-label col-md-2">Cost</label>
        <div class="col-md-1">
            <input class="form-control" type="text" id="_#__Materials_%__Cost" name="ScopeOfWork[#].Materials[%].Cost" value="">
        </div>
    </div>

//build a category drop down list here

    <input type="hidden" class="materialindex" name="ScopeOfWork[#].Materials.Index" value="%" />
</div>

<script>
    var form = $('form');
    var scope = $('#newScope');
    var material = $('#newMaterial');

    form.on('click', '.addmaterial', function () {
        var clone = material.clone();
        var scopeIndex = $(this).closest('.scope').find('.scopeindex').val();
        clone.html($(clone).html().replace(/#/g, scopeIndex));

        var materialIndex = new Date().getTime();
        clone.html($(clone).html().replace(/%/g, materialIndex));
        $(this).closest('.materials').append(clone.html());
        form.data('validator', null);
        $.validator.unobtrusive.parse(form);
    });

    $('#addScope').click(function () {
        var clone = scope.clone();
        var scopeIndex = new Date().getTime();
        clone.html($(clone).html().replace(/#/g, scopeIndex));
        $('#scopes').append(clone.html());
        form.data('validator', null);
        $.validator.unobtrusive.parse(form);
    });
</script>
@model MigratingDB.Models.ProjectViewModel
@使用(Html.BeginForm())
{
@Html.AntiForgeryToken()
项目视图模型

@Html.ValidationSummary(true,“,new{@class=“text danger”}) 动态添加工作范围和材料
} @ActionLink(“返回列表”、“索引”) 范围 工作范围 材料 材料 量 成本 //在这里建立一个类别下拉列表 变量形式=$('form'); 变量范围=$(“#新闻范围”); var材料=$(“#新材料”); 表单.on('click','addmaterial',函数(){ var clone=material.clone(); var scopeIndex=$(this).closest('.scope').find('.scopeIndex').val(); html($(clone.html().replace(/#/g,scopeIndex)); var materialIndex=新日期().getTime(); html($(clone.html().replace(/%/g,materialIndex)); $(this).close('.materials').append(clone.html()); 表单数据('验证器',空); $.validator.unobtrusive.parse(表单); }); $('#addScope')。单击(函数(){ var clone=scope.clone(); var scopeIndex=new Date().getTime(); html($(clone.html().replace(/#/g,scopeIndex)); $('#scopes').append(clone.html()); 表单数据('验证器',空); $.validator.unobtrusive.parse(表单); });

每次我创建MaterialViewModel对象并将其发布到数据库时,请帮助我为该类别构建一个dropdownlist。我有一个category表,我想在其中传递它的值以生成一个dropdownlist。我更喜欢使用强类型模型,而不是使用ViewBag

您的
ProjectViewModel
需要一个属性
IEnumerable
(或者一个包含选项值和文本的两个属性的类的
IEnumerable
),这样您就可以将选项值传递给视图(如果没有现有的
MaterialsViewModel
)。您的
MaterialsViewModel
还需要一个属性来绑定所选类别

public class ProjectViewModel
{
    // some properties..
    public IEnumerable<SelectListItem> CategoryList { get; set; }
    public IList<ScopeOfWorkViewModel> ScopeOfWork { get; set; }
}
....
public class MaterialsViewModel
{
    public int MaterialId { get; set; }
    ....
    // public int? ScopeOfWorkId { get; set; } this is not required
    public int SelectedCategory { get; set; }
    public IEnumerable<SelectListItem> CategoryList { get; set; }
}
在视图中,包含一个脚本,用于将
类别列表
转换为javascript数组

<script>
    var form = $('form');
    ....
    var categories = @Html.Raw(Json.Encode(Model.CategoryList));

    form.on('click', '.addmaterial', function () {
        ....

变量形式=$('form');
....
var categories=@Html.Raw(Json.Encode(Model.CategoryList));
表单.on('click','addmaterial',函数(){
....
然后在模板中(在`元素中),为select控件添加html(如果需要,除了标签选项外,没有任何选项)。请注意用于选择的附加类名

<div class="form-group">
    <label for="_#__Materials_%__SelectedCategory" class="control-label col-md-2">Cost</label>
    <div class="col-md-1">
        <select class="form-control category" id="_#__Materials_%__SelectedCategory" name="ScopeOfWork[#].Materials[%].SelectedCategory">
            <option value="">Please select a category</option>
        </select>
    </div>
</div>

成本
请选择一个类别
并修改脚本以根据javascript数组中的值添加选项

form.on('click', '.addmaterial', function () {
    var clone = material.clone();
    ....
    clone.html($(clone).html().replace(/%/g, materialIndex));

    // Add the options
    var select = clone.find('.category');
    $.each(categories, function(index, item) {
        select.append($('<option></option>').val(item.Value).text(item.Text));
    });

    $(this).closest('.materials').append(clone.html());
    form.data('validator', null);
    $.validator.unobtrusive.parse(form);
});
form.on('click','addmaterial',function(){
var clone=material.clone();
....
html($(clone.html().replace(/%/g,materialIndex));
//添加选项
var select=clone.find('.category');
$。每个(类别、功能(索引、项目){
select.append($('').val(item.Value).text(item.text));
});
$(this).close('.materials').append(clone.html());
表单数据('验证器',空);
$.validator.unobtrusive.parse(表单);
});

请注意,您没有为现有项目呈现任何html,因此如果有任何内容无效,并且您返回了视图,则用户动态添加的所有数据都将丢失-您需要嵌套
,以便循环该项目。并且您没有呈现html,以便对动态添加的元素进行验证。

您的
项目视图模型需要一个属性y
IEnumerable
(或包含选项值和文本的两个属性的类的
IEnumerable
),以便您可以将选项值传递给视图(如果没有现有的
MaterialViewModel
)。您的
MaterialViewModel
还需要一个属性来绑定所选类别

public class ProjectViewModel
{
    // some properties..
    public IEnumerable<SelectListItem> CategoryList { get; set; }
    public IList<ScopeOfWorkViewModel> ScopeOfWork { get; set; }
}
....
public class MaterialsViewModel
{
    public int MaterialId { get; set; }
    ....
    // public int? ScopeOfWorkId { get; set; } this is not required
    public int SelectedCategory { get; set; }
    public IEnumerable<SelectListItem> CategoryList { get; set; }
}
在视图中,包含一个脚本,用于将
类别列表
转换为javascript数组

<script>
    var form = $('form');
    ....
    var categories = @Html.Raw(Json.Encode(Model.CategoryList));

    form.on('click', '.addmaterial', function () {
        ....

变量形式=$('form');
....
var categories=@Html.Raw(Json.Encode(Model.CategoryList));
表单.on('click','addmaterial',函数(){
....
然后在模板中(在`元素中),为select控件添加html(但不带任何选项)