【问题标题】:MVC Equivalent of button click eventMVC 等价于按钮点击事件
【发布时间】:2015-04-15 07:05:47
【问题描述】:

MVC5 EF6

我已经启动了一个 MVC 应用程序,一切顺利 - 创建/编辑/删除视图都运行良好。

我已经到了“标准”@Html.TextBoxFor/@Html.EditorFor 等可以满足我需要的地步。

我正在创建一个具有类别的产品。大约有 10 个父类别,每个类别可以有多个子类别,每个子类别可以有多个子类别等,因此标准控件不能提供良好的用户体验 - 脚手架代码有一个组合框。

我已经实现了一个在“树视图”中显示所有类别的模式 - 它实际上是嵌套的 <ul></ul>。例如http://jsfiddle.net/umutc1/eyf9q87c/ 但我在每个树节点都有一个按钮,树是动态生成的:

@helper TreeView(ICollection<Heisenberg.Models.Category> categoryTree)
{
foreach (var item in categoryTree)
{
    <li>
        @if (item.Category1.Count > 0)
        {
            @Html.ActionLink(@item.CategoryID.ToString(), "SelectCategory", new { id = @item.CategoryID })

            <ul>
                @TreeView(item.Category1)
            </ul>
        }
        else
        {

            @Html.ActionLink(@item.CategoryID.ToString(), "SelectCategory", new { id = @item.CategoryID })

        }
    </li>
}
}

到目前为止一切顺利。我遇到的问题,并且由于我是 MVC 新手而无法解决 - 如何编码,以便当用户单击按钮时,模型会更新以包含 CategoryID。

如您所见,我使用的是 ActionLink 而不是标准按钮,并且在我的控制器中有这个:

    public ActionResult SelectCategory([Bind(Include = "ProdID,CategoryID")] Product product, int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Category category = db.Categories.Find(id);
        if (category == null)
        {
            return HttpNotFound();
        }

        product.CategoryID = id.GetValueOrDefault();

        return View(product);
    }

这显然行不通。 categoryID 正常,但 return View(product); 出错 - 它试图将我发送到 http://localhost:61217/Products/SelectCategory/163,但它不会退出,我只想返回 Product Create 页面,其中包含我刚刚选择的 CategoryID 的产品模型。

对于等价于 asp 按钮单击事件,我是否处于正确的轨道上?还是我应该完全不同?

【问题讨论】:

  • 你的动作链接只传递了一个参数id给方法,所以应该只是public ActionResult SelectCategory(int id)
  • 如果我理解正确,您想创建一个具有指定类别的新产品,在这种情况下,您的链接应该指向ProductController 上的一个方法(比如)public ActionResult Create(int id),您可以在其中初始化一个新建Product,根据id参数设置类别,然后返回创建新Product的视图,所以链接为@Html.ActionLink(@item.CategoryID.ToString(), "Create", "Product", new { id = @item.CategoryID }, null)
  • 谢谢。好的,让我试一试。不过,此时我已经在“创建产品”页面上 - 这不会“放弃”该产品以及我输入的任何其他数据,例如标题,然后打开一个新页面?
  • 如果是这样,你为什么还要调用控制器方法?如果您在“产品创建”页面上,那么您需要做的就是将所选类别分配给表单中的控件。
  • 为此,您将需要 javascipt/jquery - 您根本不需要链接。您需要将类别 id 值存储为关联元素 - data-id="@item.CategoryID",然后处理元素 .click() 事件,检索值 - var id = $(this).data('id'); 并将其分配给与类别属性关联的任何控件。您没有向您展示模型或视图,因此无法更具体。不过您可能对this article 感兴趣

标签: asp.net-mvc asp.net-mvc-5


【解决方案1】:

感谢@StephenMuecke,我设法解决了这个问题。

这是我所做的: 在我的创建页面上,我有一个 CategoryID 的 HiddenField

@Html.HiddenFor(model => model.CategoryID, new { @class = "form-control", @id = "tbCategoryID" })

和一个文本框,用于在选择后放置类别名称 - 这不是必需的,但有助于用户反馈他们实际上选择了一个类别:

@Html.TextBox("CategoryName", null, new { @class = "form-control", @id = "tbCategoryName", @readonly = "readonly" })

我的树视图/嵌套 &lt;li&gt; 的每个节点都有一个 &lt;span&gt;category 和 data-id 和 data-categoryname 属性来存储这些详细信息以供以后使用。

<span class="leaf closemodal category" data-id="@item.CategoryID" data-categoryname="@item.CategoryName"> @item.CategoryName</span>

然后我使用 Javascript 为这些 &lt;span&gt; 添加了 onclick 函数:

$('span.category').click(function () {
                var id = $(this).data('id');
                var name = $(this).data('categoryname');
                $('#tbCategoryID').val(id);
                $('#tbCategoryName').val(name);
            });

添加此点击功能意味着当用户点击其中一个&lt;span&gt; 时,它会从span 的data-XXX 属性中获取id 和名称。然后该函数将 ID 和 NAME 添加到适当的字段 - HiddenField 和文本框。

提交表单后,类别 ID 将回传给控制器。

【讨论】:

    猜你喜欢
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-28
    • 2011-12-30
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多