使用 JQuery 重新加载局部视图

Posted

技术标签:

【中文标题】使用 JQuery 重新加载局部视图【英文标题】:Reloading Partial View with JQuery 【发布时间】:2013-01-03 08:58:51 【问题描述】:

我有一个页面,顶部有一个视频和一个可供您选择的视频列表。目前,单击视频列表中的链接将重新加载整个页面。我需要它来仅刷新页面顶部包含视频的部分视图。

我在这里看到了几篇关于 SO 的帖子,展示了如何使用 JQuery 重新加载部分视图,但在我的情况下无法使其正常工作。我不确定如何传递正确的视频 ID。

控制器:

    public ActionResult Videos(int topVideo = 0)
    
        VideosModel model = new VideosModel();
        model.Videos = StatsVideoService.GetEntityList(new Lookup(TableStatsVideo.IsDeleted, false)).OrderByDescending(x => x.DateCreated).ToList();

        if (topVideo == 0)
            model.TopVideo = model.Videos.First();
        else
        
            model.TopVideo = model.Videos.Where(x => x.StatsVideoId == topVideo).FirstOrDefault();
            if (model.TopVideo == null)
                model.TopVideo = model.Videos.First();
        

        return View(model);
    

查看:

@model Project.Models.VideosModel

<section class="videos">
    <div id="top_video">
        @html.RenderPartial("StatsVideo", Model.TopVideo);
    </div>

    <ul>
        @foreach (var item in Model.Videos)
        
            <li>
                <div class="videoList">
                    <a href ="@Url.Action("Videos", "Home", new  topVideo = item.StatsVideoId )">
                        <img src="@Url.Content("~/Content/img/video-ph.png")" />
                    </a>
                    <p class="videoTitle">@item.Title</p>
                </div>
            </li>
        
    </ul>
</section>

如果需要更多信息,请告诉我。

【问题讨论】:

【参考方案1】:

在用头撞墙几个小时后,我开始工作了!作为对将来查看本文的任何其他人的参考,以下是我的工作方式:

我设置链接的onclick指向一个javascript方法,传入视频的id作为参数:

    @foreach (var item in Model.Videos)
    
        <li>
            <div class="videoList">
                <a href ="#" onclick="updateTopVideo(@item.StatsVideoId)">
                    <img src="@Url.Content("~/Content/img/video-ph.png")" />
                </a>
                <p class="videoTitle">@item.Title</p>
            </div>
        </li>
    

然后我在底部的视图中包含了这个脚本:

<script>
    var updateTopVideo = function (itemId) 

        var url = '@Url.Content("~/Home/StatsVideo/")';
        url = url + itemId;
        $.get(url, "", callBack, "html");
    ;

    var callBack = function (response) 
        $('#top_video').html(response);
    ;
</script>

最后,我向控制器添加了一个方法,该方法将返回屏幕顶部视频所需的部分视图:

    public ActionResult StatsVideo(int Id)
    
        IStatsVideo vid = StatsVideoService.GetEntity(new Lookup(TableStatsVideo.StatsVideoId, Id));
        if (vid == null)
            vid = StatsVideoService.GetEntityList(new Lookup(TableStatsVideo.IsDeleted, false)).OrderByDescending(x => x.DateCreated).FirstOrDefault();

        return PartialView(vid);
    

这段代码应该很容易理解。基本上,onclick 调用第一个 javascript 方法,然后调用控制器。控制器构建局部视图并返回它。第一个 javascript 方法将其传递给第二个 javascript 方法,该方法将 div "top_video" 的 html 设置为返回的部分视图。

如果有任何不妥之处,或者将来有人遇到问题,请告诉我,我会尽力提供帮助。

【讨论】:

嗨,埃里克,$('#top_video').html(response);它不适合我。【参考方案2】:

我认为这里可能有几个令人困惑和不一致的元素。

首先,您返回的是完整视图而不是局部视图。这会重新加载所有包含的元素,而不仅仅是与您的局部视图相关的部分。

其次,您正在使用 Url.Action,它只生成 url。我建议使用 Ajax.ActionLink,它允许您进行完全 ajax 调用、刷新部分 div 的内容并更新目标 div 元素。

代替:

<div class="videoList">
                <a href ="@Url.Action("Videos", "Home", new  topVideo = item.StatsVideoId )">
                    <img src="@Url.Content("~/Content/img/video-ph.png")" />
                </a>
                <p class="videoTitle">@item.Title</p>
            </div>

尝试更现代的解决方案

<div class="videoList">
@Ajax.ActionLink(
"Videos", 
"Home", 
"new  topVideo = item.StatsVideoId , 
new AjaxOptions   
    HttpMethod = "GET", 
    OnSuccess = "handleSuccess" 

)
</div>

通过这种方式,您可以非常具体地指定每个链接要执行的操作,并且可以传递多个参数以及定义回调函数。您还可以在 ajax 选项中使用“UpdateTargetId”将新刷新的局部视图加载到 DOM 元素中。

【讨论】:

我明白这一点。我知道我的控制器中需要一个新方法来返回新视频的部分视图。我不知道如何通过 jquery 调用它并让结果覆盖当前在 'top_videos' div 中的内容。 我不确定我是否 100% 理解您的问题。你是说你需要知道 Ajax.ActionLink 的 jquery 等价物是什么吗?或者你是在问如何用你的控制器方法的结果覆盖你的“top_videos”div? 好的,我在链接中添加了一个 onclick:onclick="updateTopVideo(@item.StatsVideoId)" 然后我创建了一个 main.js 文件并将其包含在视图中。该脚本文件的内容是:var updateTopVideo = function (itemId) $.get('/Home/StatsVideo/' + itemId, "", callBack) ; var callBack = function (response) $('#top_video').html(response) ; 最后,我在控制器中添加了一个名为 StatsVideo 的新方法,用于返回带有所选视频 id 参数的局部视图。看起来这应该可行,但我没有在我的控制器中达到断点。 嗯,应该的。您是否在提琴手中看到请求触发?如果是这样,您是否使用 HttpGet 标签装饰了您的控制器?这应该指示路由查找传入的 get 调用。 我将控制器中的方法从public ActionResult StatsVideo(int StatsVideoId) 更改为public ActionResult StatsVideo(int Id),现在可以使用了。我不知道参数名称必须是特定的工作!【参考方案3】:

您可以删除图像周围的内容,并将Url.Action 生成的 url 存储在 data-href 属性中。

然后就可以使用jquery load方法来加载数据了:

$(".videolist>img").click(function () 
    $("#content").load($(this).data("href"));
);

我在这里创建了一个动态加载内容的小提琴,因此您可以根据需要使用它:http://jsfiddle.net/bTsLV/1/

【讨论】:

以上是关于使用 JQuery 重新加载局部视图的主要内容,如果未能解决你的问题,请参考以下文章

使用 JQuery 调用局部视图

从局部视图加载的 jQuery 自动完成结果

部分视图问题 - 未定义 jQuery

重新加载后如何将数据传递给局部视图

如何加载包含 JavaScript 的局部视图?

动态局部视图 + jquery 表单劫持 + 客户端验证 = 不工作