简体   繁体   中英

Refreshing MVC 3 PartialView via JavaScript

I'm having a ASP.NET MVC 3 view containing several PartialViews. One of them gets an image from the internet which depends on parameters of its ViewModel. I'd like to change the parameters of the ViewModel and reload that PartialView (only) so that the image with the changed parameter is loaded.

Here's my PartialView so far:

@model MyViewModel

<script type="text/javascript">
function changeParameter(newValue) {
    @Model.Parameter = newValue;
    alert(@Model.Parameter);
    ... What now? How do I refresh the PartialView? ...
}
</script>

<h4>@Model.Header</h4>
<table style="background-color: #f8f7f8; width:100%;">
<tr style="line-height:18px; background-color: #d6d6d6;">
    <th style="cursor:pointer" onclick="changeParameter('value1');">Value1</th>
    <th style="cursor:pointer" onclick="changeParameter('value2');">Value2</th>
    <th style="cursor:pointer" onclick="changeParameter('value3');">Value3</th>
    <th style="cursor:pointer" onclick="changeParameter('value4');">Value4</th>
    <th style="cursor:pointer" onclick="changeParameter('value5');">Value5</th>
    <th style="cursor:pointer" onclick="changeParameter('value6');">Value6</th>
    <th style="cursor:pointer" onclick="changeParameter('value7');">Value7</th>
</tr>
</table>
<img src="@Model.ImageUrl" alt="Chart" />

So the thing is that I want to click one of the values (Value1-7) and the Parameter variable of my ViewModel is changed. So far it works, as the alert box shows the value I just set. I now want to reload the PartialView so that @Model.Header as well as @Model.ImageUrl are updated as they depend on the parameter that I changed. How can I do this? Oh by the way, I'm totally new to JavaScript...

Cheers,
Simon

EDIT:
Ok, the two answers above did help a little, but as I am a real JavaScript noob it's kind of hard...
What I have now is:

@model MyViewModel
<div id="my-header">
    <h4>@Model.Header</h4>
</div>

<table id="my-table" style="background-color: #f8f7f8; width:100%;">
    <tr style="line-height:18px; background-color: #d6d6d6;">
    <th style="cursor:pointer" id="value1">Value1</th>
    <th style="cursor:pointer" id="value2">Value2</th>
    <th style="cursor:pointer" id="value3">Value3</th>
    <th style="cursor:pointer" id="value4">Value4</th>
    <th style="cursor:pointer" id="value5">Value5</th>
    <th style="cursor:pointer" id="value6">Value6</th>
    <th style="cursor:pointer" id="value7">Value7</th>
    </tr>
</table>

<div id="my-image">
    <img src="@Model.ImageUrl" alt="Chart" />
</div>

<script type="text/javascript">
    $('#my-table th').click(function() {
        alert(this.id);
        @Model.Parameter = this.id;
        $('#my-header').html("<h4>@Model.Header</h4>");
    });
</script>

That is good so far, but I can't manage to manipulate the Property Parameter from my Model class. So the call @Model.Parameter = anyValue; doesn't work.
How can I do this in JavaScript?

EDIT 2: Ok, I finally solved it the way chaZm suggested. The JSON way.
But first of all I changed my ViewModel so that all possible URLs and headers are stored in a Dictionary<string, string> . Then my PartialView is:

@model MyViewModel
<div id="my-header">
    <h4>@Model.Header</h4>
</div>

<table id="my-table" style="background-color: #f8f7f8; width:100%;">
    <tr style="line-height:18px; background-color: #d6d6d6;">
    <th style="cursor:pointer" id="value1">Value1</th>
    <th style="cursor:pointer" id="value2">Value2</th>
    <th style="cursor:pointer" id="value3">Value3</th>
    <th style="cursor:pointer" id="value4">Value4</th>
    <th style="cursor:pointer" id="value5">Value5</th>
    <th style="cursor:pointer" id="value6">Value6</th>
    <th style="cursor:pointer" id="value7">Value7</th>
    </tr>
</table>

<div id="my-image">
    <img src="@Model.ImageUrl" alt="Chart" />
</div>

<script type="text/javascript">
    $('#my-table th').click(function() {
        var urls = @Html.Raw(Json.Encode(@Model.Urls));
        var url = urls[this.id];
        $('#my-image').html("<img src='" + url + "' alt='Chart' />");
        var headers = @Html.Raw(Json.Encode(@Model.Headers));       
        var header = headers[this.id];
        $('#my-header').html(header);
    });
</script>

Now everything works as it meant to be...
Thanks for your efforts.

Well. There are 2 ways to update MVC page.

1) Full page refresh (you simply call controller action, it forms new view with updated parameters)

2) AJAX update. Javascript know nothing about what server thing you use. MVC \ ASP>NET, anything. So what you need is call controller which would return you new partial view values. Here you can return partial Value from server as

    public PartialViewResult Result()
    {
        return PartialView("Viewname",params);
    }

and then assign returned html to some container with jquery like

    $('div').load("/Result",....)

OR

You can return updated data via JSONResult like

    public JsonResult Result()
    {
        return Json(GetSomeValidJson());
    }

and then format the page you like in JS. You getting Json, parsing it and setting manually all page data you like

I didn't work with MVC 3 for too long (only 1 and 2) so there could be some updates in that area. But the basic are the same i think. Good luck!

By using a partial to are virtually merging it into the page. The web browser has no idea that that section of the page was from a partial (since MVC takes care of everything server side). What I have done in the past when I need a certain section of the page to update is to create a separate action which returns just the value in the partial. The partial doesn't need to include any <head> or <body> tags, just the content. Then, on the client side, AJAX that data in.

For example, create a controller called MyAJAXPartials and an action for this section called MyPartial (I would change these names if I were you). Then, make that action render a regular view (not a partial), but use the same code as you posted above. Using onclick="..." is not the preferred way to do action binding, if you are using jQuery (and you give the table an ID), you can do:

$('#TABLE-ID th').each(function() {
    $(this).click(function() {
        changeParameter($(this).text()));
    });
});

Again, instead of using the partial, on the main page build a frame form the content with a <div> tag, give it an id like contentArea, and use the following JavaScript (again, I assume you have jQuery):

$.get('/MyAJAXPartials/MyPartial', function(data) {
    $('#contentArea').html(data);
    // PUT THE CHANGE PARAMETER CODE I SUGGESTED ABOVE HERE
});

Then, each time that you need to change the data, just reload the content in that frame by requesting a new URL. For example, instead of requesting /MyAJAXPartials/MyPartial , it could be /MyAJAXPartials/MyPartial/Value1 . All of the JavaScript should be outside of that frame.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM