简体   繁体   中英

How to data-bind content for an iframe using KnockoutJS?

Can anyone please tell me how to bind data to an iframe using Knockout? I have tried to do this as below, but it is not working as expected:

<iframe data-bind ="attr: { src: testcontent}"></iframe>

And Javascript:

var ViewModel = function (content) {
     this.testcontent = ko.observable(content);
};

ko.applyBindings(new ViewModel("Hello World!!"));

I want to add the text "Hello Content" into the iframe . Can anyone please help me on this?

Warning: this obviously has security implications! Only do this with code from sources you absolutely trust.

Here's a basic, straightforward solution to build on. It allows you to have an observable with an entire html structure, and fill the iFrame with that data. If you update the html, the iframe is updated with the new version:

ko.bindingHandlers.iframeContent = {
    update: function(element, valueAccessor) {
        var value = ko.unwrap(valueAccessor());
        element.contentWindow.document.close(); // Clear the content
        element.contentWindow.document.write(value);
    }
};

ko.applyBindings({
    myHtml: ko.observable("<html>\n<head><title>Test</title></head>\n<body>\n\nMy <em>fine</em> text.\n\n</body>\n</html>")
});

You can use this like this in your view:

<p>Edit your html:</p>
<textarea data-bind="value: myHtml, valueUpdate: 'afterkeydown'"></textarea>

<p>And see it appear in an iframe:</p>
<iframe data-bind="iframeContent: myHtml"></iframe>

See this jsfiddle for a demo. The valueUpdate is merely there so the demo is clearer, it's debatable if that's a good idea in bigger scenarios.

EDIT: Fiddle Updated.

http://jsfiddle.net/sujesharukil/NnT78/10/

You need to create a custom binding handler for this. I have used one such by http://jsfiddle.net/mbest/GYRUX/

and changed it to suit your needs. Take a look at both and see what works for your needs.

ko.bindingHandlers.bindIframe = {
    init: function(element, valueAccessor) {
        function bindIframe() {
            try {
                var iframeInit = element.contentWindow.initChildFrame,
                    iframedoc = element.contentDocument.body;
            } catch(e) {
                // ignored
            }
            if (iframeInit)
                iframeInit(ko, valueAccessor());
            else if (iframedoc){
                var span = document.createElement('span');
                span.setAttribute('data-bind', 'text: someProperty');
                iframedoc.appendChild(span);
                ko.applyBindings(valueAccessor(), iframedoc);
            }
        };
        bindIframe();
        ko.utils.registerEventHandler(element, 'load', bindIframe);
    }
};

You can have the code like this, works absolutely fine :-

// This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
            function AppViewModel() {
                this.externalUrl = ko.observable("http://www.w3schools.com");

            }

            // Activates knockout.js
            ko.applyBindings(new AppViewModel());

OR

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Test IFrame</title>
    <script src="Scripts/jquery-1.7.1.js"></script>

    <script src="Scripts/knockout-2.2.1.js"></script>
    <script>
        $(document).ready(function () {
            // This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
            function AppViewModel() {
                this.externalUrl = "http://www.w3schools.com";

            }

            // Activates knockout.js
            ko.applyBindings(new AppViewModel());
        });

    </script>
</head>
<body>
    <iframe class="iframe" id="iframe" style="width: 700px; height: 700px" data-bind="attr: { src: externalUrl }"></iframe>

</body>
</html>

thats the best code ever it worked with 2+ iframes..... cant run on chrome it has no server path unless your on a server.. but works in IE as desktop file....

nice job Sujesh Arukil

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM