javascript 从父视图提交局部视图数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27267942/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 07:15:36  来源:igfitidea点击:

Submitting partial view data from parent view

javascriptjqueryasp.net-mvcrazor

提问by Nitin Sawant

How to submit partial view data from parent view .

如何从父视图提交部分视图数据。

I am newbie to MVC,
I have created a partial view _CurrentDatawhich contains editor controls - textbox etc
and added Submit button in the main view:

我是 MVC 的新手,
我创建了一个局部视图_CurrentData,其中包含编辑器控件 - 文本框等,
并在主视图中添加了提交按钮:

<div class="row">
    <div class="col-md-12">
        @Html.Partial("_CurrentData", Model.CurrentItemDetails)
    </div>
</div>
<div class="row">
    <div class="col-md-2 col-md-offset-5">
        <div>
            <input type="button" class="btn btn-primary" value="Submit" id="btnSubmit"/>
            &nbsp;&nbsp;
            <input type="button" class="btn btn-primary" value="Cancel" id="btnCancel" />
            <br/><br />
        </div>
    </div>
</div>

ViewModel

视图模型

public class ProductionViewModel
{
    public ItemDetails CurrentItemDetails { get; set; }
}

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

View

看法

<div class="panel panel-default">
    <div class="panel-heading">
        <h3 class="panel-title">Editor</h3>
    </div>
    <div class="panel-body">
        <div class="row form-group">
            <div class="col-sm-4 control-label text-right">
                <strong>Name:</strong>
            </div>
            <div class="col-sm-8 control-label">
                @Html.TextBoxFor(m => m.Name , new { @class = "form-control" })
            </div>
        </div>
    </div>
</div>

now on clicking of 'btnSubmit' I want to submit data from _CurrentDataview to the server and then refresh the partial view,
How to accomplish this?

现在单击“btnSubmit”,我想将数据从_CurrentData视图提交到服务器,然后刷新部分视图,
如何完成此操作?

回答by Inspector Squirrel

What you're asking for

你要什么

The functionality you're asking for is AJAX. AJAX requests are 'Asynchronous', which at the most basic level means HTTP requests can be initiated and responded to without the need to refresh the page.

您要求的功能是 AJAX。AJAX 请求是“异步”的,这在最基本的层面上意味着可以发起和响应 HTTP 请求,而无需刷新页面。

As someone wrote in comment to your question, jQuery can be used and does provide a nice way to do AJAX requests, but a lot of people would probably cry if you included the entire jQuery library just for an AJAX request.

正如有人在对您的问题的评论中所写的那样,可以使用 jQuery 并且确实提供了一种很好的方式来执行 AJAX 请求,但是如果您仅针对 AJAX 请求包含整个 jQuery 库,很多人可能会哭。

JavaScript

JavaScript

So in JavaScript this is a liiiiiittlebit more complicated, there are some examples here. I'm not going to show you how to do it in JavaScript simply because I don't have a lot of time right now, but I might update the answer later. I would probably advise looking into doing it this way if you can.

因此,在JavaScript中,这是一个liiiiiittle更有点复杂,有一些例子在这里。我不会仅仅因为我现在没有很多时间而向您展示如何在 JavaScript 中做到这一点,但我可能会在稍后更新答案。如果可以的话,我可能会建议您考虑这样做。

jQuery

jQuery

In jQuery this is easy. The documentation for AJAX requests is here.

在 jQuery 中,这很容易。AJAX 请求的文档在这里

Basically what you need to do is make a request to the server so it can update your partial view dataand then return the new partial view for you to replace your current HTML with. It would look something like:

基本上,您需要做的是向服务器发出请求,以便它可以更新您的局部视图数据,然后返回新的局部视图以供您替换当前的 HTML。它看起来像:

$.fn.serializeObject = function () {
    var o = {};
    var a = this.serializeArray();
    $.each(a, function () {
        if (o[this.name]) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

$.ajax({
    url: '@Url.Content("~/Controller/_CurrentData")',
    type: 'POST',
    data: {
        //partialViewForm relates to the form element in your partial view
        model: JSON.stringify($('#partialViewForm').serializeObject());
    },
    success: function (response) {
        if (response) {
            //partialViewDiv relates to the div in which your partial view is rendered
            $('#partialViewDiv').html(response);
        }
    },
    error: function (xhr, ajaxOptions, thrownError) { alert(xhr.status); alert(thrownError); }
});

The above would assume you had something like this as your controller method:

上面假设你有这样的东西作为你的控制器方法:

[HttpPost]
public ActionResult _CurrentData(ItemDetails model)
{
    //do stuff with model here
    return PartialView("_CurrentData", model);
}

So this is basically how you'd contact the controller. In order to call that ajax from your webpage, you'd need to have a button in your partial view within the form that you can override using event.preventDefault().

所以这基本上就是你联系控制器的方式。为了从您的网页调用该 ajax,您需要在表单中的部分视图中有一个按钮,您可以使用event.preventDefault().

回答by MstfAsan

Actually there is no statement like partial viewor parent viewwhen you look at the situation in browser side. Browser only sees a html document. Html.Partialespecially PartialViewsare only meaningful in server side and they are there to help you indeed. It gives you ability to reuse partial views on multiple page and one place to modify all. When Razorrendering this cshtml file ,starts to render from top to bottom and when it encounters @Html.Partial("something")it executes that method which returns Html encodedstringand displays the returned string. After all, Razor returns one complete html page. So when you submitdata from your html only important thing is which input type has which name attribute.

实际上,在浏览器端查看情况时,并没有像局部视图父视图这样的语句 。浏览器只能看到一个 html 文档。Html.Partial特别是PartialViews只在服务器端有意义,它们确实可以帮助你。它使您能够在多个页面上重用部分视图,并在一个地方修改所有视图。当Razor渲染这个 cshtml 文件时,开始从上到下渲染,当它遇到@Html.Partial("something")它时它会执行该方法,该方法返回Html 编码的字符串并显示返回的字符串。毕竟,Razor 返回一个完整的 html 页面。所以当你提交来自您的 html 的数据唯一重要的是哪个输入类型具有哪个 name 属性。

Solution 1: Without AjaxYour get method is like this according to your main view.

解决方案1:没有Ajax根据您的主视图,您的get方法是这样的。

// GET: Item
        public ActionResult MainView()
        {
            var _itemDetail = new ItemDetails { ID = 1, Name = "Item1" }; //you get this item somewhere maybe db
            var pvm = new ProductionViewModel();
            pvm.CurrentItemDetails = _itemDetail;  //add item to viewmodel
            return View(pvm);
        }

i am assuming that you have form tags,, just change your button type to submit

我假设您有表单标签,只需更改您的按钮类型即可提交

@using(Html.BeginForm()){
<div class="row">

    <div class="col-md-12">

        @Html.Partial("_CurrentData", Model.CurrentItemDetails)

    </div>
</div>
<div class="row">
    <div class="col-md-2 col-md-offset-5">
        <div>
            <input type="submit" class="btn btn-primary" value="Submit" id="btnSubmit" />
            &nbsp;&nbsp;
            <input type="button" class="btn btn-primary" value="Cancel" id="btnCancel" />
            <br /><br />
        </div>
    </div>
</div>
}

And add your post action to controller, this is perfectly fine.

并将您的发布操作添加到控制器,这非常好。

[HttpPost]
        public ActionResult MainView(ItemDetails submittedItem)
        {
            //do stuff with model like persistence
            var pvm = new ProductionViewModel();
            pvm.CurrentItemDetails = submittedItem;
            return View(pvm);
        }

This will return same view with new item

这将返回与新项目相同的视图

Solution 2:Ajax Using JqueryThis solution is already given. You will have two option ; return partial view from server and replace older content with the one returned from server or return json and change the content by dom manipulation. Two approach have downsides. Sippy's answer is perfect what i want to add is instead of jquery ajax method load method is more reasonable for returning static view.

解决方案 2:使用 Jquery 的 Ajax这个解决方案已经给出。您将有两个选择;从服务器返回部分视图并将旧内容替换为从服务器返回的内容或返回 json 并通过 dom 操作更改内容。两种方法都有缺点。Sippy 的回答是完美的,我想添加的是,而不是 jquery ajax 方法 load 方法对于返回静态视图更合理。

$("#partialViewDiv").load('@Url.Content("~/Controller/_CurrentData")');

Solution 3:Using two way data binding or framework like AngularWhen you wanna refresh your partial view you may need some extra information that is server generated like id of newly created item. This is why you need to talk to server cause you already have the new input values for partial view on the fly. May be you want to display all saved item in a list in somewhere in the same page and after created item returned from server you have to add it manually. So if your page needs situation like that best way is using frameworks like angular. This way you can refresh your partial view and make a lot things with no effort. My Demo just for demonstration you can follow many design principles.

解决方案 3:使用两种方式数据绑定或框架(如 Angular)当您想刷新部分视图时,您可能需要一些服务器生成的额外信息,例如新创建的项目的 id。这就是为什么您需要与服务器交谈的原因,因为您已经有了用于动态局部视图的新输入值。可能您想在同一页面的某个位置的列表中显示所有保存的项目,并且在从服务器返回创建的项目后,您必须手动添加它。因此,如果您的页面需要这样的情况,最好的方法是使用 angular 等框架。这样你就可以刷新你的局部视图并毫不费力地做很多事情。我的 Demo 仅用于演示,您可以遵循许多设计原则。

This is main view

这是主视图

<div ng-app="ItemApp" ng-controller="ItemController">
    <form name="newTopicForm" data-ng-submit="save()">
        <div class="row">
            <div class="col-md-12">
                @Html.Partial("_CurrentData", Model.CurrentItemDetails)
            </div>
        </div>
        <div class="row">
            <div class="col-md-2 col-md-offset-5">
                <div>
                    <input type="submit" class="btn btn-primary" value="Submit" id="btnSubmit" />
                    &nbsp;&nbsp;
                    <input type="button" class="btn btn-primary" value="Cancel" id="btnCancel" />
                    <br /><br />
                </div>
            </div>
        </div>
    </form>
</div>

Partial view

局部视图

<div class="panel panel-default">
    <div class="panel-heading">
        <h3 class="panel-title">Editor</h3>
    </div>
    <div class="panel-body">
        <div class="row form-group">
            <div class="col-sm-4 control-label text-right">
                <strong>Name:</strong>
            </div>
            <div class="col-sm-8 control-label">
    @Html.TextBoxFor(m => m.Name, new { @class = "formcontrol",data_ng_model="item.name",data_ng_init="item.name="+"'"[email protected]+"'"})
            </div>
        </div>
    </div>
</div>

Textbox is binded to item.name with ng-model attribute so we no need to worry about refreshing view. When item.name changes view changes too.(two way data binding)Include angular js and this is custom js

文本框通过 ng-model 属性绑定到 item.name,因此我们无需担心刷新视图。当 item.name 更改时,视图也会更改。(双向数据绑定)包括angular js,这是自定义js

var myApp = angular.module('ItemApp', []);
myApp.controller('ItemController', function ($scope, $http,$q) {
    $scope.itemList = {};
    $scope.save = function () {
        $http.post("mainview", $scope.item).
        then(function (result) {

         $scope.item.name = result.data.Name; //update from server
                                              //it is enoguh to refresh 
                                              //your partial view data
         itemList.splice(0, 0, result.data);//add list may be you need to
                                               //display in the view
        },
        function () {
            console.log(error);
        });
    };
});

And server side code

和服务器端代码

[HttpPost]
        public ActionResult MainView(ItemDetails SubmittedItem)
        {
            //do stuff with model like persistence
            SubmittedItem.ID = 1;

            return Json(SubmittedItem);
        }

You just need to deal with object all view operations are done by two way data bindig when using angular.

使用angular时,您只需要处理对象所有视图操作都是通过两种方式数据绑定完成的。

回答by codebot

Yes , Either the main view is a plain HTML or comprised of multiple partial view + main view , when it renders in browser ,It will be consider as one single HTML not the parts .by saying that, you will have the access to the DOM's either it is in the partial view or Main View.So, from my personal experience it doesn't matter where we place the submit button if you have decided using the Jquery post method by constructing your own model/view model to help it.

是的,主视图是纯 HTML 或由多个部分视图 + 主视图组成,当它在浏览器中呈现时,它将被视为一个单独的 HTML 而不是部分。这样说,您将可以访问 DOM无论是在局部视图还是主视图中。所以,根据我的个人经验,如果您决定通过构建自己的模型/视图模型来帮助它使用 Jquery post 方法,那么我们将提交按钮放在哪里并不重要。

but yes there are some situations you will be having partial update buttons at each level of the partial view by using

但是是的,在某些情况下,您将在部分视图的每个级别使用部分更新按钮

@using (Ajax.BeginForm

回答by Amirhossein Mehrvarzi

Solution 1:

解决方案1

You can simply wrap inputs in main page inside an Ajax formelement and also call the @Html.Partial("_CurrentData", Model.CurrentItemDetails)inside it and everything will work fine.

您可以简单地将input主页中的 s包装在 Ajaxform元素中,并调用@Html.Partial("_CurrentData", Model.CurrentItemDetails)它的内部,一切都会正常进行。

Solution 2:

解决方案2

Without using formtag with some JavaScript code to find target inputs just after clicking on btnSubmitelement (define click event) then serializethem to prepare for sending to server's action method.

在单击btnSubmit元素(定义单击事件)之后,无需使用form带有一些 JavaScript 代码的标记来查找目标,然后它们序列化以准备发送到服务器的操作方法。input

Common part of both Solutionsis writing an ajax method which responds to update the page without refresh like :

两个解决方案的共同部分是编写一个 ajax 方法,该方法响应更新页面而无需刷新,例如:

public JsonResult GetResponse(ItemDetails model) {            
    return Json(/*data*/, /*behavior*/);
}