JQuery事件与ASP.NET MVC局部视图不兼容

26
我正在尝试让 ASP.NET MVC 中的局部视图与 JQuery 事件配合使用。但是,当您通过 Ajax 加载局部视图之后,JQuery 似乎无法为局部视图中的任何元素触发事件。我怀疑如果您使用其他框架或 JavaScript 库来用 Ajax 加载局部 HTML 代码,则此问题也会发生。
例如,考虑以下示例:
控制器:
 public class TestController : Controller
    {

    public ActionResult Index()
    {
        return View();
    }

    public ActionResult LoadPartialView()
    {
        return View("PartialView");
    }
}

Index.aspx

     <script type="text/javascript">
         $(document).ready(function() {
             $("#button").click(function() {
                 alert('button clicked');
             });
         });   
     </script>    

     <div>
     <%using(Ajax.BeginForm("LoadPartialView", new AjaxOptions { UpdateTargetId="PartialView"})){ %>
        Click <input type="submit" value="here" /> to load partial view.
     <% } %>
     </div>
     <br /><br />
     <% Html.RenderPartial("PartialView"); %>

PartialView.ascx

<div id="PartialView">
   Click <input type="button" id="button" value="here"></input> to display a javascript message.
</div>

一旦页面第一次加载完成,您可以单击“单击此处显示JavaScript消息”,然后会收到一个JavaScript警告消息,其中包含“按钮已单击”字样。但是,一旦您单击“单击此处加载部分视图”,单击应该弹出JavaScript警告消息的按钮不再有任何效果。似乎“单击”事件不再被触发。
有人知道为什么使用JQuery会出现这个问题,以及如何解决吗?此问题也在其他使用事件的JQuery插件中出现。
5个回答

53

我找到了一个解决方案:

只需要尝试做出以下改变:

$(document).on("click", "YOUR_SELECTOR", function(e){
  /// Do some stuff ...
});

不是:

$("YOUR_SELECTOR").on("click", function(e){
  /// Do some stuff ...
});

谢谢!这对我有用,而且是一个非常简单的解决方案。然而,我不够了解这种方法和.live()方法之间的优缺点。 - Trunker
@Trunker .live()已经过时了。"从jQuery 1.7开始,.live()方法已被弃用。使用.on()来附加事件处理程序。使用旧版本的jQuery的用户应优先使用.delegate()。" - Wowe
@PEOudin,感谢您的回答,它对我很有帮助!奇怪的是,这个问题只出现在MVC 5中(在将MVC 3应用程序重构为MVC 5之后)。对于MVC 3,“$(“YOUR_SELECTOR”).on(...”版本可以正常工作而没有任何问题。也许有人能解释一下这是为什么? - Wowe
@PeOudin 很棒的答案,终于对我有用了,我已经找了两个小时的答案! - AlexGH
1
如果您有一个页面加载后动态内容的局部视图,这里有一个类似的解决方案。希望能帮到某些人。 - Shaiju T
我想知道为什么这个部分视图可以工作,而另一个却不行?期待您的解释。谢谢! - Willy David Jr

9

处理这个问题最简单的方法是使用live()方法:

<script type="text/javascript"> 
         $(document).ready(function() { 
             $("#button").live('click', function() { 
                 alert('button clicked'); 
             }); 
         });    
</script>  

1
太棒了。这确实有效。根据官方文档,live()可以用于将处理程序附加到与当前选择器匹配的所有元素的事件,现在或将来。唯一的缺点是编写插件的其他人显然没有使用live方法。因此,为了使其与现有插件配合使用,某人可能需要深入源代码并进行调整。 - dritan
True。或者在内容添加到页面后,您可以再次调用插件,而不仅仅是在页面加载时。如果答案足够满意,请将其标记为已接受... - mkedobbs
2
此答案已过时,请查看PEOudin的答案。 - Martin at Mennt

1
<script>
   $(document).ready(function(){
      $("input[id^=button]").live('click', function() { 
               //Your Code     

    }); 
});
</script>

0

对我也起作用的是将jquery内容放在部分视图中。只需确保仅引用已加载视图中的控件,否则可能会为控件注册两次处理程序。

PartialView.ascx:

<div id="PartialView">
   Click <input type="button" id="button" value="here"></input> to display a javascript message.
</div>
<script type="text/javascript">
     $(document).ready(function() {
         $("#PartialView").find("#button").click(function() {
             alert('button clicked');
         });
     });   
 </script>  

0

这些解决方案都对我没用,所以我不得不做以下事情才能使它工作:

  1. 我创建了一个部分视图,并将所有的JavaScript引用放在那个文件中
  2. 我创建了一个像这样的div
<div id="js">
       @Html.Partial("[Your_Path]")
</div>

3. 当我加载一些局部页面后,我会在JavaScript中执行以下操作:

$('#js').load('/Your_Controller/Your_Partial_function');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接