Javascript 使用window.open()并为新窗口中的视图传递knockoutjs ViewModel
我目前正在开发一个应用程序,它需要在浏览器中单击按钮打开一个新窗口,然后当用户在主窗口的文本框中键入内容时,新窗口将相应地更新。我以前使用过knockout,但由于某些原因,我在更新第二个windows视图时遇到了问题。这是我目前的代码Javascript 使用window.open()并为新窗口中的视图传递knockoutjs ViewModel,javascript,knockout.js,Javascript,Knockout.js,我目前正在开发一个应用程序,它需要在浏览器中单击按钮打开一个新窗口,然后当用户在主窗口的文本框中键入内容时,新窗口将相应地更新。我以前使用过knockout,但由于某些原因,我在更新第二个windows视图时遇到了问题。这是我目前的代码 //main.js $(function () { var viewModel = new ViewModel(); ko.applyBindings(viewModel); var newwindow;
//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("");
};
这是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>
//index.html
新窗口
这是第二个窗口的代码,当用户单击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>
//newwindow.html
$(函数(){
var viewModel=窗口。\u viewModel;
应用绑定(视图模型);
$(“#警报视图模型”)。单击(函数(){
警报(viewModel.textbox());
});
});
显示texbox值
当用户在主页上的文本框中键入时,该页上的span标记将自动更新。当用户单击“新建窗口”按钮时,新窗口会弹出用户刚刚输入的文本,当用户继续在主窗口文本框中键入时,辅助窗口中的span标记不会更新。但是,当用户按下“显示文本框值”按钮时,文本将显示在警报框中,并已更新!因此,我的问题是,为什么第二个窗口中的span标记在ViewModel明显更新时没有更新(因为“show texbox value”按钮显示的值)
快速评论:
出于某种原因,通过window.open(“somepath”)访问文件;在这个问题的背景下,它实际上不能正常工作。我发现我需要在一个小型HTTP服务器中加载新的窗口文件,并将“somepath”设置为实际的url。(这就是为什么这个问题没有附带一些示例代码的原因)。如果两个窗口共享相同的视图模型,则它们也必须共享相同的
ko
实例。这是因为用一个敲除实例创建的可观察对象不能用另一个实例
下面是一个使用iframe
的示例,但相同的原则适用于窗口。打开:
家长:;儿童:
父代码:
childWindow = ...;
childWindow.initChild(ko, viewModel);
子代码:
window.initChild = function(ko, viewModel) {
window.ko = ko;
ko.applyBindings(viewModel, document.body);
}
正如Michael提到的,您只需将绑定应用于打开的窗口的主体,如下所示:
var mywindow = window.open('', '', 'height=400,width=600');
mywindow.document.write('<input id="testText" type="text" data-bind="textInput: text1"/>');
ko.applyBindings(viewmodel, mywindow.document);
我们的输入(将复制到弹出窗口)
相同的输入只是为了表明这是可行的:)
我认为您无法在两个浏览器窗口之间进行这样的通信。事实上,他们在HTML5中提出了一些新的东西,这表明它并不是这么简单。如果我试图从另一个域打开这个窗口,它确实会更难。然而,因为我不是,这是完全有效的,并且有效。我对这件事有异议,真是令人震惊。在这里,我发现了一个有趣的问题。我们一直在尝试这样做——似乎它在淘汰赛3中被打破,回滚到2.3.0,并且运行良好。上面的示例适用于淘汰赛3.1.0。如果您可以重现使用JSFIDLE发现的问题,我将看看是否可以提供帮助。