【问题标题】:Knockout template binding elements aren't available after an ajax callajax 调用后敲除模板绑定元素不可用
【发布时间】:2013-02-18 18:11:58
【问题描述】:

我无法绑定到由 afterRender 事件中的 AJAX 调用触发的 Knockout 模板创建的元素。正如您在Fiddle 中看到的那样,结果正确呈现,但在 afterRender 事件处理程序中,元素仍然不可用。

问题...

  • 模板在 afterRender 事件处理程序运行时似乎没有渲染,如何正确渲染?

  • 为什么 AJAX 调用会影响结果?如果取消注释掉 AJAX 调用上方的行,则模板元素在 afterRender 事件中可用。

这里是代码...

HTML

<div id="plugin" data-bind="template: { name: 'fooTemplate', data: $data, afterRender: postProcess }"></div>
<br />
<br />
<hr />
<div id="results"></div>

<script type="text/html" id="fooTemplate">
    <div data-bind="foreach: items()">
        <span data-bind="text: displayText"></span>
    </div>
</script>

JAVASCRIPT

var data = {
    items: [{
        displayText: 'Name',
    }, {
        displayText: 'Last Login Date',
    }, {
        displayText: 'Email',
    }]
};

function DataModel() {
    var self = this;
    self.items = ko.observableArray([]);
    self.data = ko.dependentObservable(function () {
        //self.items(data.items);//   <<== UNCOMMENT THIS LINE AND THE postProcess FUNCTION SHOWS FULLY RENDERED DOM
        $.ajax({
            url: '/some/path',
            error: function () {
                self.items(data.items);
            }
        });
    });

    postProcess = function () {
        $('#results').text($('#plugin').html());
    }
}

dataModel = new DataModel();
ko.applyBindings(dataModel);

注意...小提琴对虚假地址进行 AJAX 调用。这样 Fiddle 就没有服务器依赖项了。错误属性用于更改导致模板运行的数据。但是,在我的开发环境中调用有效的 url 会产生与小提琴中显示的结果相同的结果。另外,我没有使用从服务器返回的数据来加载模板。而是小提琴在顶部使用静态定义的数据源(再次只是为了演示问题)。

【问题讨论】:

    标签: javascript knockout.js


    【解决方案1】:

    查看您的示例,您遇到了异步问题。

    在没有 $.ajax 调用的情况下,流程是这样工作的:

    1. dependentObservable 触发更新值
    2. self.items 使用新值更新
    3. 模板呈现
    4. 调用了 postProcess 方法,一切正常。

    但是对于 $.ajax 调用,完成(和错误)方法是回调,因此流程会发生变化:

    1. dependentObservable(使用 ko.computed!)触发更新值
    2. 对服务器进行 $.ajax 调用。
    3. 完成(或错误)回调将排队等待完成。
    4. 模板呈现
    5. 调用了 postProcess 方法,但 self.items 仍为空。
    6. 在服务器响应并更新 self.items 后触发 done 回调
    7. 渲染的模板仍绑定到您的视图模型,因此渲染的模板已更新。

    我认为最简单的解决方法是将您的 ajax 调用从您的dependentObservable 中拉出,以允许您注释掉的情况。

    【讨论】:

    • 感谢您的解释。小提琴是我的整体解决方案的一个精简示例,它需要 AJAX 从服务器获取数据。如何更改小提琴以支持使用 AJAX 并解决异步问题?
    • 我知道在大型应用程序中使用 sn-p 会很困难。这是它可能工作的一种方式的概念:jsfiddle.net/jeljeljel/nSPsM
    • 谢谢,我认为这与我在原始帖子中分享的小提琴相同。您的意思是使用其他网址吗?
    • 是的,我做到了。我丢失了更新的小提琴。如果您仍然需要它,我可以尝试重新创建它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多