【问题标题】:$(document).ready() not firing after updating view component$(document).ready() 更新视图组件后未触发
【发布时间】:2020-07-30 07:33:57
【问题描述】:

我正在将我的部分视图移动到视图组件,因为根据 Microsoft 的组件明显优于部分视图,尤其是在处理复杂视图时..

对于我现在移植到视图组件的部分视图,我有很多 jQuery 脚本。通常我在 $(document).ready() 函数中调用我的 jQuery 组件,如下所示:

$(document).ready(function(){
    Component1.init();
    Component2.init();
    ....
})

这个逻辑非常有用,因为这些视图必须多次更新。因此,当有部分视图时,组件会重新初始化,因为当部分视图文档在更新后准备好时,$(document).ready() 函数总是会触发。

但是,转到查看组件时,我仍然尝试这样做。不幸的是,我意识到$(document).ready() 仅在视图组件准备就绪时才被触发——这意味着,在更新视图组件时,$(document).ready() 函数不会被触发,因此不会初始化 jQuery 组件。我正在使用标准的 Ajax 调用来定位返回视图组件的控制器 - 一切正常,除了 $(document).ready() 函数在更新后没有被触发。

注意

一种解决方法是在 ajax 成功响应中初始化我的组件。这可行,但不是可取的。

  • 这是怎么回事?
  • 为什么我的$(document).ready() 函数在更新视图组件后没有触发?
  • 如何正确解决这个问题,以便在视图组件准备好后初始化我的所有 jQuery 组件?

示例:

//view with component
<div id="Component">
    <vc:mycomponent lead="Model.Lead"></vc:mycomponent>
</div>

//Script Inside component
<script>
    $(document).ready(function () {
        Component.init();
    });
    var Component = (function () {
        var $button;
        var $component

        var init = function() {
             cacheDom();
             handlers();
        }
        var cacheDom = function(){
            var $button = $('#button1')
            var $component = $('#Component')
        }
        var handlers = function () {
            $button.on('click', function() {
                handleclick();
            })
        }
        var handleClick = function(){
            $.ajax({
                url: 'Controller/ViewComponent',
                type: 'GET',
                success: function (response) {
                    $component.html(response);
                }
            });
        }
        return {init : init}
    })

</script>

【问题讨论】:

  • 您能否添加一个以前有效但现在无效的具体示例(精简到最低限度以显示应该有效的内容)?在进行 AJAX 调用之前不应触发 onReady 函数,除非您正在加载的内容有自己的脚本文件。
  • 我刚刚更新了我的问题。我不确定这有什么不同。
  • 确实如此。再澄清一点:脚本是否在一个部分中加载(即@section scripts,或类似的)?
  • 不是!页面底部只是一个普通的

标签: jquery asp.net-mvc asp.net-core


【解决方案1】:

我会给你回答你只经历过第二种情况的两种情况:

问题:在 AJAX 调用后替换 HTML 后,事件处理程序(例如按钮点击)不再起作用:
解决方案

替换

$( ".myClass" ).click(function() {
  // ...
});

$('body').on('click', '.myClass', function () {
    // ..
});

问题:如何从ViewComponent 插入JavaScript? (这就是你最初提到的问题)
解决方案:这与ViewComponent的渲染时间和其他脚本(如jQuery)加载的顺序有关。

这是一个完美的答案:Javascript in a View Component
您可以创建一个标签助手,在 jQuery 加载后延迟 JavaScript 的执行。

几天前,我在这个确切的位置插入了在客户端 Ajax 调用后再次呈现 ViewComponent 后调用的 JavaScript。

<script type="text/javascript" on-content-loaded="true">
    console.log('this is being executed after loading the view component');
</script>

【讨论】:

  • 这很奇怪。我明白了你在那里所做的,但为什么我不能像以前那样使用选择器?我不太喜欢$('body').on('click', elem, func())
  • 我想这取决于您在哪里注册事件处理程序。如果您的视图中有 JavaScript 代码(视图组件将在其中呈现),如果您想开箱即用,可以更改为 $('body')....。据我了解,它与对象插入 DOM 的方式和时间有关。如果您对此事有更多了解,请分享;-) 也可以在您的$component.html(response); 调用之后重新绑定处理程序。但是通过$('body').... 使用它是一种不要忘记重新绑定处理程序的方法。
【解决方案2】:

这些脚本的运行方式有所不同。当您在初始视图上执行此操作时,

<div id="Component">
    <vc:mycomponent lead="Model.Lead"></vc:mycomponent>
</div>

<script>
    $(document).ready(function () {
        Component.init();
    });
    var Component = (function () {
        var $button;
        var $component

        /* ... your code ... */

        return {init : init}
    })
<script>

在整个页面加载时触发$(document).ready(function () { ... });

当您通过 AJAX 调用重新加载此内容时,即使 $(document).ready(function () { ... }); 仍然存在,它也永远不会被触发 - 它只会在最初构造 DOM 时触发。请参阅https://learn.jquery.com/using-jquery-core/document-ready/this Stack Overflow answer,其中还包括一个简单的解决方法。对于您的代码,我想它会像添加一样简单

Component.init();

在 AJAX 代码的完成/完成处理程序中的某个位置。

如果它之前工作过...似乎不应该有,除非您的 AJAX 调用返回的是完整页面而不是部分视图(假设 load 事件可以在您丢弃任何内容之前运行你没有注入页面)。

【讨论】:

  • 我知道这一点。再次查看我的代码 :-) 我发表了一条评论,指出 Ajax 在我的组件视图中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
  • 2011-04-27
  • 1970-01-01
相关资源
最近更新 更多