使用window.open()并在新窗口中为一个视图传递knockoutjs ViewModel

Tho*_*rin 3 javascript knockout.js

我目前正在开发一个应用程序,它需要在浏览器上单击按钮打开一个新窗口,然后当用户键入主窗口的文本框时,新窗口将相应地更新.我之前使用过淘汰赛,但由于某种原因,我在第二次更新Windows视图时遇到问题.这是我目前的代码.

//main.js
   $(function () {
        var viewModel = new ViewModel();
        ko.applyBindings(viewModel);
        var newwindow;
        $("#new-window-btn").click(function () {
            newwindow = window.open("a/path/to/newwindow.html", "New Window","status=1,width=350,height=350");
            newwindow._ViewModel = viewModel;
        });

    });

    function ViewModel() {
        var self = this;
        self.textbox = ko.observable("");
    };
Run Code Online (Sandbox Code Playgroud)

这是index.html并包含一个非常基本的按钮,它将打开新窗口,一个用户将输入的文本框和一个span标记,以显示我并不疯狂.

//index.html
<div id="new-window-btn" class="btn">new window</div>
<textarea cols="3" rows ="3" data-bind="value:textbox,valueUpdate:'afterkeydown'"></textarea>
<span data-bind="text: textbox"></span>
Run Code Online (Sandbox Code Playgroud)

这是当用户点击index.html中的新窗口按钮时弹出的第二个窗口的代码

//newwindow.html
    <script type="text/javascript">
        $(function () {
            var viewModel = window._ViewModel;
            ko.applyBindings(viewModel);
            $("#alert-viewModel").click(function () {
                alert(viewModel.textbox());
            });
        });
    </script>
<span data-bind="text:textbox()"></span>
<div id="alert-viewModel" class="btn">show texbox value</div>
Run Code Online (Sandbox Code Playgroud)

当用户键入主页面上的文本框时,该页面上的span标记会自动更新.当用户点击新窗口按钮时,新窗口会弹出用户刚输入的文本,当用户继续键入主窗口文本框时,辅助窗口中的span标记不会更新.但是,当用户按下"显示文本框值"按钮时,文本将显示在警告框中,并且已经更新!所以我的问题是为什么我的span标签在第二个窗口中没有更新,当ViewModel显然已经更新(因为"show texbox value"按钮显示的值).

快速评论:由于某种原因通过window.open("somepath")访问文件; 在这个问题的背景下实际上并没有正常工作.我发现我需要在一个小的HTTP服务器中加载新的窗口文件,并使"somepath"成为一个实际的URL.(这就是为什么没有一些示例代码附加到这个问题).

Mic*_*est 9

如果两个窗口ko共享相同的视图模型,则它们也必须共享相同的实例.这是因为使用一个Knockout实例创建的observable不能用于不同的实例.

这是一个使用的示例iframe,但相同的原则适用于window.open:

家长:http://jsfiddle.net/eZMTM/ ; 孩子:http://jsfiddle.net/GrXhv/7/

家长代码:

childWindow = ...;
childWindow.initChild(ko, viewModel);
Run Code Online (Sandbox Code Playgroud)

子代码:

window.initChild = function(ko, viewModel) {
    window.ko = ko;
    ko.applyBindings(viewModel, document.body);
}
Run Code Online (Sandbox Code Playgroud)