Renderuj częściowy widok za pomocą jQuery w ASP.NET MVC

223

Jak renderować widok częściowy za pomocą jquery?

Możemy renderować częściowy widok w następujący sposób:

<% Html.RenderPartial("UserDetails"); %>

Jak możemy zrobić to samo za pomocą jquery?

Prasad
źródło
Możesz również spojrzeć na poniższy artykuł. tugberkugurlu.com/archive/... Podąża za innym podejściem i ulepsza sposób.
tugberk
Głupie pytanie. Czy UserDetails jest widokiem częściowym jako strona cshtml: UserDetails.cshtml? Próbuję załadować częściowy widok. I normalnie użyłbym: @ Html.Partial ("~ / Views / PartialViews / FirstPartialViewTwo.cshtml")
George Geschwend
1
@GeorgeGeschwend, Nic nie jest tu głupie, dopóki ktoś nie zareaguje. UserDetails (UserDetails.cshtml) to widok częściowy w kontrolerze użytkownika. Tak jak w komentarzach do zaznaczonej odpowiedzi, lepiej jest użyć Url.Action zamiast twardego kodowania pełnej ścieżki widoku.
Prasad

Odpowiedzi:

286

Nie można renderować widoku częściowego przy użyciu tylko jQuery. Możesz jednak wywołać metodę (akcję), która wyświetli widok częściowy i doda go do strony przy użyciu jQuery / AJAX. Poniżej znajduje się moduł obsługi kliknięcia przycisku, który ładuje adres URL działania z atrybutu danych na przycisku i odpala żądanie GET, aby zastąpić DIV zawarty w widoku częściowym zaktualizowaną zawartością.

$('.js-reload-details').on('click', function(evt) {
    evt.preventDefault();
    evt.stopPropagation();

    var $detailDiv = $('#detailsDiv'),
        url = $(this).data('url');

    $.get(url, function(data) {
        $detailDiv.replaceWith(data);         
    });
});

gdzie kontroler użytkownika ma akcję o nazwie szczegół, która:

public ActionResult Details( int id )
{
    var model = ...get user from db using id...

    return PartialView( "UserDetails", model );
}

Zakłada się, że częściowy widok jest kontenerem o identyfikatorze, detailsDivwięc wystarczy zastąpić całą rzecz zawartością wyniku wywołania.

Przycisk widoku rodzica

 <button data-url='@Url.Action("details","user", new { id = Model.ID } )'
         class="js-reload-details">Reload</button>

Userto nazwa kontrolera i detailsnazwa akcji w @Url.Action(). Widok częściowy UserDetails

<div id="detailsDiv">
    <!-- ...content... -->
</div>
tvanfosson
źródło
Wciąż otrzymuję złe żądanie z tego przykładowego kodu, który podałeś. Skopiowałem tak, jak jest i właśnie zmieniłem akcję kontrolera, do której powinna się udać. Nie jestem pewien, do czego służy „użytkownik”.
chobo2,
1
Użyłem tylko „prawdopodobnych” nazw kontrolerów i akcji, ponieważ nie zawierałeś żadnego kodu, który moglibyśmy przejść. Po prostu zastąp „szczegóły” działaniem, a „użytkownik” nazwą kontrolera.
tvanfosson
1
Jeszcze raz dziękuję za świetną odpowiedź tvanfosson.
jakiś pomysł, jak to będzie działać z Razor? próbował $ .get ("@ Url.Action (\" Manifest \ ", \" Upload \ ", nowy {id =" + klawisz + "})", funkcja (dane) {$ ("<div />") .replaceWith (data);});
Patrick Lee Scott
1
@Zapnologica - jeśli ponownie ładujesz całą tabelę, może być konieczne ponowne zastosowanie wtyczki, ponieważ elementy DOM, do których był pierwotnie podłączony, zostały zastąpione. Lepiej byłoby połączyć go z metodą, która zwraca dane jako JSON, datatables.net/examples/data_sources/server_side.html
tvanfosson
152

W tym celu wykorzystałem ładowanie ajax:

$('#user_content').load('@Url.Action("UserDetails","User")');
Prasad
źródło
46
Generalnie myślę, że lepiej jest iść z pomocnikiem Url.Action zamiast mocno kodować ścieżkę. To się zepsuje, jeśli twoja strona internetowa znajduje się w podkatalogu, a nie w katalogu głównym. Korzystanie z pomocnika rozwiązuje ten problem i pozwala dodawać parametry z dynamicznie ustawianymi wartościami.
tvanfosson
18
Możesz zrobić $ ('# user_content'). Load ('@ Url.Content ("~ / User / UserDetails")'), aby to obejść - często używam tej metody, jeśli potrzebuję javascript, aby uderzyć w parametry querystring na końcu
adresu
Czy w tej odpowiedzi UserDetailsnazwa akcji nie jest częściowym widokiem, prawda?
Maxim V. Pavlov,
4
@Prasad: Urls powinny być zawsze oceniane przy użyciu @Url.Action("ActionName","ControllerName", new { area = "AreaName" } )robi zamiast Handcoding .
Imad Alazani
3
@PKKG. @ Url.Action () ocenia tylko w Razor. to nie działa, jeśli OP chce umieścić swój kod w osobnym pliku js i odwołać się do niego.
Michael
60

@tvanfosson kołysze swoją odpowiedzią.

Sugerowałbym jednak ulepszenie js i małą kontrolę kontrolera.

Kiedy użyjemy @Urlpomocnika do wywołania akcji, otrzymamy sformatowany HTML. Lepiej byłoby zaktualizować content ( .html), a nie faktyczny element ( .replaceWith).

Więcej informacji na stronie: Jaka jest różnica między jQuery's replaceWith () i html ()?

$.get( '@Url.Action("details","user", new { id = Model.ID } )', function(data) {
    $('#detailsDiv').html(data);
}); 

Jest to szczególnie przydatne w drzewach, w których zawartość można zmieniać kilka razy.

W kontrolerze możemy ponownie wykorzystać akcję w zależności od requestera:

public ActionResult Details( int id )
{
    var model = GetFooModel();
    if (Request.IsAjaxRequest())
    {
        return PartialView( "UserDetails", model );
    }
    return View(model);
}
Custodio
źródło
11

Kolejną rzeczą, którą możesz wypróbować (na podstawie odpowiedzi tvanfosson), jest:

<div class="renderaction fade-in" 
    data-actionurl="@Url.Action("details","user", new { id = Model.ID } )"></div>

A następnie w sekcji skryptów na stronie:

<script type="text/javascript">
    $(function () {
        $(".renderaction").each(function (i, n) {
            var $n = $(n),
                url = $n.attr('data-actionurl'),
                $this = $(this);

            $.get(url, function (data) {
                $this.html(data);
            });
        });
    });

</script>

To renderuje twoją @ Html.RenderAction za pomocą ajax.

Aby wszystko było fanowskie, możesz dodać efekt przenikania za pomocą tego css:

/* make keyframes that tell the start state and the end state of our object */
@-webkit-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
@-moz-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
@keyframes fadeIn { from { opacity:0; } to { opacity:1; } }

.fade-in {
    opacity: 0; /* make things invisible upon start */
    -webkit-animation: fadeIn ease-in 1; /* call our keyframe named fadeIn, use animattion ease-in and repeat it only 1 time */
    -moz-animation: fadeIn ease-in 1;
    -o-animation: fadeIn ease-in 1;
    animation: fadeIn ease-in 1;
    -webkit-animation-fill-mode: forwards; /* this makes sure that after animation is done we remain at the last keyframe value (opacity: 1)*/
    -o-animation-fill-mode: forwards;
    animation-fill-mode: forwards;
    -webkit-animation-duration: 1s;
    -moz-animation-duration: 1s;
    -o-animation-duration: 1s;
    animation-duration: 1s;
}

Man I love mvc :-)

Piotr
źródło
Dlaczego każdy z was działał? Jak to działa? Czy masz coś takiego: data-actionurl = "@ Url.Action (" details "," user ", new {id = Model.ID} data-actionurl =" Another Action "?
user3818229
Nie, każda funkcja zapętla wszystkie elementy HTML, które mają atrybut data-actionurl i wypełnia go, wywołując zapytanie ajax dla metody akcji. Tak wiele <div class="renderaction fade-in" ...></div>elementów.
Peter
9

Musisz utworzyć akcję na kontrolerze, która zwróci renderowany wynik częściowego widoku lub kontroli „UserDetails”. Następnie wystarczy użyć polecenia Pobierz lub Wyślij z jQuery, aby wywołać akcję, aby wyświetlić renderowany HTML.

Chris Pietschmann
źródło
jak ustawić interwał czasowy, aby odświeżyć zaktualizowane dane w tej funkcji jQuery
Neeraj Mehta
5

Korzystanie ze standardowego wywołania Ajax, aby osiągnąć ten sam wynik

        $.ajax({
            url: '@Url.Action("_SearchStudents")?NationalId=' + $('#NationalId').val(),
            type: 'GET',
            error: function (xhr) {
                alert('Error: ' + xhr.statusText);

            },
            success: function (result) {

                $('#divSearchResult').html(result);
            }
        });




public ActionResult _SearchStudents(string NationalId)
        {

           //.......

            return PartialView("_SearchStudents", model);
        }
DevC
źródło
0

Zrobiłem to w ten sposób.

$(document).ready(function(){
    $("#yourid").click(function(){
        $(this).load('@Url.Action("Details")');
    });
});

Metoda szczegółowa:

public IActionResult Details()
        {

            return PartialView("Your Partial View");
        }
Van
źródło
0

Jeśli potrzebujesz odwoływać się do dynamicznie generowanej wartości, możesz również dołączyć parametry ciągu zapytania za @ URL.

    var id = $(this).attr('id');
    var value = $(this).attr('value');
    $('#user_content').load('@Url.Action("UserDetails","User")?Param1=' + id + "&Param2=" + value);


    public ActionResult Details( int id, string value )
    {
        var model = GetFooModel();
        if (Request.IsAjaxRequest())
        {
            return PartialView( "UserDetails", model );
        }
        return View(model);
    }
Jeździec Harrison
źródło