【问题标题】:Pass ViewModel with jQuery post?使用 jQuery 帖子传递 ViewModel?
【发布时间】:2011-03-23 17:02:56
【问题描述】:

我正在尝试在 MVC 应用程序中使用 jQuery 发布帖子,根据此处的 SO 答案: Can jQuery do a POST of a ViewModel to a Controller in ASP.NET MVC?

不同的是我用它来删除动态视图中的一个项目(不要介意我直接发布删除,这是一个授权关闭的站点,我将使用 jQuery 来确认,我只是不希望用户必须转到新页面)。因此,我需要能够同时发送 id 和 ViewModel(ViewModel 在删除之前保存任何添加的项目)。总的来说,我对这个解决方案并不特别满意,但在这一点上,我只需要让它发挥作用!

所以我试图弄清楚如何根据上面的 SO 帖子发送 id 和 ViewModel,但我无法弄清楚如何使用命名参数获取 ViewModel。这不起作用:

$(".delete").click(function () {
    $.ajax({
        type: "POST",
        url: deleteurl,
        data: ({id : $(this).closest('tr').find('td:first').text(),vm: $('form').serialize()}),
        cache: false,
        success: function (html) {
            $("#rows").html(html);
        }
    });
    return false;
});

这是 POST 操作方法:

        [HttpPost]
        public ActionResult Delete(int id, LanguageViewModel vm)
        {
            for (int i = 0; i < vm.Languages.Count; i++)
            {
                var language = _repository.GetLanguage(vm.Languages[i].Id); //This is the key, get the original program object to update
                UpdateModel(language, "Languages[" + i + "]");
            }
            _repository.Save();
//Delete code will go here
         return RedirectToAction("Edit", "Languages", new { id = id });
        //return View();
        }

同样,它不起作用,它甚至没有到达调试器中的操作方法。如果我从 action 方法中删除 int id 参数,它实际上会到达那里,但是 vm = null。我不知道该怎么做,所以任何帮助将不胜感激!

编辑: 对不起,返回值现在应该是改变了,而不是返回 View()。

更新:

在达林的一点帮助下,它几乎可以工作了:

    [HttpPost]
    public ActionResult Delete(LanguageViewModel vm, FormCollection collection)
    {
        for (int i = 0; i < vm.Languages.Count; i++)
        {
            var language = _repository.GetLanguage(vm.Languages[i].Id); //This is the key, get the original program object to update
            UpdateModel(language, "Languages[" + i + "]");
        }
        _repository.Save(); 
        int id = Int32.Parse(collection["HiddenId"]);
        Language languageToDelete = _repository.GetLanguage(id);
        _repository.Delete(languageToDelete);
        vm.Languages.Remove(vm.Languages.SingleOrDefault(l => l.Id == id));
        _repository.Save();
        return PartialView("LanguageList", vm);
    }

但是我已经更改为返回一个 PartialView(这是我从一开始就应该做的事情,因为这就是 jQuery 所做的 - 加载一个带有结果的 div)。但问题是,在从 action 方法返回这个 Partial View 并使用 jQuery 将其加载到 div 中后,$(".delete").click jQuery 函数不再起作用......

有什么想法吗?

【问题讨论】:

    标签: jquery asp.net asp.net-mvc-3 viewmodel


    【解决方案1】:

    您可以尝试在表单中包含一个隐藏字段来保存 id:

    <input type="hidden" name="id" id="hiddenid" value="" />
    

    然后:

    $('.delete').click(function () {
        var id = $(this).closest('tr').find('td:first').text();
        $('#hiddenid').val(id);
        $.ajax({
            type: 'POST',
            url: deleteurl,
            data: $('form').serialize(),
            cache: false,
            success: function (html) {
                $('#rows').html(html);
            }
        });
        return false;
    });
    

    可以简化为:

    $('.delete').click(function () {
        var id = $(this).closest('tr').find('td:first').text();
        $('#hiddenid').val(id);
        $('#rows').load(deleteurl, $('form').serialize());
        return false;
    });
    

    【讨论】:

    • 好的,但是我将如何在 action 方法中同时获取 id 和 ViewModel 呢?在您的示例中,action 方法中的参数应该是什么才能同时获得这两个参数?
    • @Anders Svensson,您不需要修改您的操作方法签名。使用此代码,您应该在操作中同时获得 id 和视图模型。只需确保您的视图模型上没有名为 id 的属性,否则您可能会得到奇怪的结果。
    • 好吧,我按你说的试了试,还是连action方法都达不到,只发form作为参数,这种情况下签名不会出错吧?而且我仍然不明白该方法如何仅因为我将其放在 hiddenid 输入中就可以访问该 id?
    • @Anders Svensson,因为您将它放在隐藏字段中,所以当您执行 $('form').serialize() 并包含在请求中时,它将与其他表单值一起序列化。此外,如果您使用.load() 版本而不是$.ajax(),请查看FireBug 是否使用GET 或POST 请求,因为您的操作标有[HttpPost],并且它只接受POST 请求。因此,如果您发送 GET 请求,它将不会被命中。可能还有其他原因导致该操作未命中,例如 javascript 错误,...所以使用 FireBug 进行分析。
    • 在您的帮助下,我实际上得到了它,但必须进行一些更改,见上文。我并不是说我喜欢我的代码,但我越来越接近现在可以工作的东西。但是还有一个大问题:jQuery 在返回部分视图后无法在 id=add 链接上工作......知道为什么吗?
    【解决方案2】:

    您是否尝试在发布前将 id 附加到 deleteurl?

    这样的事情对我有用:

    deleturl = deleteurl + "/" + id;
    

    第,

    \^/i l l

    【讨论】:

    • 我没试过,但我可以试一试,但我似乎记得,如果你在 ajax 方法中有一个数据参数,它会覆盖 url 中的参数或其他东西,我'我不确定。但我会检查的!
    【解决方案3】:

    如何将 FormCollection 作为第二个参数而不是 viewmodel 传递。然后,您可以在保存和/或删除之前对您的语言对象执行 TryUpdateModel。

    【讨论】:

    • 恐怕这不会有帮助,我需要这里传入的 ViewModel。视图的动态方面(在同一个视图中编辑、添加和删除)需要不同的更新代码(我已经尝试在这个论坛中找到更简单的方法......)
    猜你喜欢
    • 2011-06-30
    • 1970-01-01
    • 2021-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多