Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
910 views
in Technique[技术] by (71.8m points)

asp.net mvc - Scripts not working on partial view after Ajax call

I have called scripts on _Layout.cshtml page and my Index.cshtml page has partial view into it. So on page load, SignalR scripts working perfect on partial view, on page end I make another ajax request and load the partial view with another data filled in that and embed under already displayed data, and then the SignalR does not work on the newly embedded record.

This is my index page code:

<div class="col-md-6">
    <div class="profile-body">            
        <div class="row infinite-scroll">
            @Html.Partial("_AlbumRow", Model)
        </div>
    </div>
</div>

This is my partial View Code:

@model IEnumerable<SmartKids.Lib.Core.ViewModels.FileMediaAlbumsVM>
@foreach (var item in Model)
{   
<div class="widget">
    <div class="block rounded">            
        <img src="@Url.Content(item.ImageUrl)" alt="@item.Title">
        <input type="button" data-image-id="@item.imageId" class="btn btn-sm btn-default">Like</input>
    </div>
</div>
}

Kindly help me how to resolve this issue that after making an ajax request I am not able to get those SignalR working. Here is more to say when I put the SignalR scripts on PartialView that works but it also sucks that on each ajax request there is again SignalR loaded on the page and when I click on LIke button it makes many calls to the function behind it. Kindly help me to resolve this issue, I am stuck at this point since 1 week.

Here is signalR Code:

        $(".btn.btn-sm.btn-default").on("click", function () {
            var imageId = $(this).attr("data-image-id");
            albumClient.server.like(imageId);
        });
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Problem: You are binding event to elements directly, So when you remove this element and replace it with a different one the events are also removed along with that element, This is something like strongly coupled.

Solution: Use Jquery event delegation. This will make sure the events will be triggered on the current elements and also all the elements that can come in future.

syntax is as below.

$(document).on("click", ".btn.btn-sm.btn-default",function () {
    var imageId = $(this).attr("data-image-id");
    albumClient.server.like(iamgeId);
});

NOTE: This was never a singlaR issue, it was Jquery issue.


Efficient Way: The problem in using $(document).on("click"... is that when ever there is a click happening on the entire page the Jquery framework will bubble the events from the clicked element upwards(its parent, and its parent and so on..) unless the element specified in the selector arrives, So its kind of performance hit as we don't want this check's to run if we are clicking outside the required area ( button .btn.btn-sm.btn-default in this example).

So best practice is to bind this event delegation to the closest parent possible which will not be removed, <div class="row infinite-scroll"> in this question. So that only when the click happens within this element the event bubbling will happen and also will be stopped once it reaches the parent element,it acts kind of a boundary for event bubbling.

   $('.row.infinite-scroll').on("click", ".btn.btn-sm.btn-default",function () {
        var imageId = $(this).attr("data-image-id");
        albumClient.server.like(iamgeId);
    });

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...