【问题标题】:Knockoutjs: manually bind specific dynamic iframe in foreach to parentKnockoutjs:手动将 foreach 中的特定动态 iframe 绑定到父级
【发布时间】:2014-02-21 14:12:56
【问题描述】:

我有一个类似的问题:Knockoutjs: bind dynamic iframes in foreach to parent,得到了回答,但现在我试图更进一步地处理这个示例,使用 ajax 调用并在其中一个 iframe 中加载异步内容...

我正在尝试动态绑定输出 iframe 和父窗口,以便我可以更改/更新 iframe 或父窗口中的可观察或可观察数组,并且两个视图都将更新为新值。

除了http://jsfiddle.net/NnT78/66/ 的第一个 iframe 之外,您可以看到这对所有 iframe 都有效

这是我的代码

HTML:

<iframe data-bind="attr: {src: src, 'data-asyncload': async}, bindIframe: $root"></iframe>

KnockoutJS:

ko.bindingHandlers.bindIframe = {
    update: function (element, valueAccessor) {
            function bindIframe() {
                try {
                    var iframeInit = element.contentWindow.initChildFrame,
                        iframedoc = element.contentDocument.body;
                } catch (e) {
                    // ignored
                }
                var val = valueAccessor();
                if (iframeInit)
                    iframeInit(ko, valueAccessor());
                else if (iframedoc) {
                    ko.applyBindings(valueAccessor(), iframedoc);
                }
            };

            if($(element).data("asyncload") == false) {
                bindIframe();
                ko.utils.registerEventHandler(element, 'load', bindIframe);
            }
        }
};

第一个 iframe 将有一个异步调用,它将在上面的原始绑定之后加载内容,这就是为什么我跳过上面的这个 iframe 的绑定:

if($(element).data("asyncload") == false) {

要绑定第一个 iframe(在异步调用完成并从数据源加载内容之后),我想调用一个函数来绑定该特定 iframe:

function bindAsyncOnLoadCallback() {
    $("iframe[data-asyncload='true']").each(function() {
    try {
        var iframeInit = this.contentWindow.initChildFrame,
            iframedoc = this.contentDocument.body;
    } catch (e) {
        // ignored
    }
    if (iframeInit)
        iframeInit(ko, new ViewModel());
    else if (iframedoc) {
        ko.applyBindings(new ViewModel(), iframedoc);
    }
});
};

bindAsyncOnLoadCallback() 中的绑定似乎没有绑定到父窗口,我想我这行写错了??

ko.applyBindings(new ViewModel(), iframedoc);

您可以在http://jsfiddle.net/NnT78/66/看到除第一个绑定到父窗口之外的所有 iframe 的工作示例

我想这样做的原因是我在加载到页面上的异步内容中有链接,并且需要在加载 ajax 内容后应用绑定

提前致谢!!

【问题讨论】:

  • 在你最后的小提琴中,ViewModel 函数是在底部的 IIFE 中定义的,你的 bindAsyncOnLoadCallback 函数无法访问。更正之后,它可以在延迟绑定调用时工作(需要加载内容)。 jsfiddle.net/rniemeyer/myq8e
  • 感谢您的回复。从您发布的小提琴似乎仍然无法正常工作?我需要输出 observable 数组和 Click Me 链接才能像其他 iframe 一样工作(将新项目推送到 observable 数组)
  • 它似乎对我有用(在第二帧中) - 标有async=true 的那个。 foreach 循环之外的第一帧仍然无法工作。
  • 在您的小提琴中...jsfiddle.net/rniemeyer/myq8e 当您在 async=true 框架中单击“单击我”时,它应该更新外部文档中的“值:”和其他 iframe 中的“someProperty”,就像如果您在其他 iframe 中单击“单击我”,它就可以工作
  • 哦- 那是因为它是一个不同的 ViewModel 实例。

标签: iframe knockout.js


【解决方案1】:

我得到了这个工作!这是工作示例:http://jsfiddle.net/myq8e/48/

问题是我必须在一个变量中全局声明ViewModel(),这样我才能在异步回调函数中使用它:

var viewModel = new ViewModel();

然后在为父窗口应用绑定时使用viewModel

ko.applyBindings(viewModel);

对于异步 iframe:

function bindAsyncOnLoadCallback() {
    $("iframe[data-asyncload='true']").each(function() {
        try {
            var iframeInit = this.contentWindow.initChildFrame,
                iframedoc = this.contentDocument.body;
        } catch (e) {
            // ignored
        }
        if (iframeInit)
            iframeInit(ko, viewModel);
        else if (iframedoc) {
            ko.applyBindings(viewModel, iframedoc);
        }
    });
}

【讨论】:

  • 很酷的诡计。总是很高兴看到人们用 Knockout 做疯狂的事情。您可能希望确保在公开该 viewModel 时正确考虑安全性。
  • 哦,看看这个,让你的价值更新更加壮观:) jsfiddle.net/myq8e/49
  • 感谢@Milimetric!也感谢您的安全提示。我查看了您的小提琴以查看壮观的更新 :) 但没有发现任何不同??
  • 对文本框的更新会立即反映到 iframe。基本上,onkeydown 与 onblur 相对。
猜你喜欢
  • 1970-01-01
  • 2012-10-15
  • 1970-01-01
  • 1970-01-01
  • 2013-02-08
  • 1970-01-01
  • 2021-11-26
  • 2013-01-16
  • 2016-05-26
相关资源
最近更新 更多