【问题标题】:Passing data between views in Durandal在 Durandal 中的视图之间传递数据
【发布时间】:2013-07-08 20:38:28
【问题描述】:

我有一个带有网格的视图,从那里我在新窗口中启动不同的视图。父视图需要将数据传递给子视图,并且它不能作为查询字符串传递,因为它非常大。我不能使用本机模式。我只是使用 window.open 并没有创建自定义模式上下文。我尝试过的事情

1.尝试使用以下代码在新窗口中填充隐藏字段元素

var popup = window.open('/#/viewname');
popup.onload=function(){document.findbyid('hiddenfield')= newvalue };

我正在使用启动页面显示 durandal 中的加载,路由器仍在导航的新窗口的加载,我得到启动页面文档

2。尝试在子视图中要求父视图,然后使用以下代码获取父视图数据

define(['viewmodels/parent'],function ('parent'){

function activate(){
localvariablevalue= parent.observable;



}

return{
activate:activate
}

});

我将 parent.observable 视为未定义。由于这是一个新窗口,因此很可能与上下文无关。

3.尝试了一个单例 global.js 文件并在父子节点中都需要它,但我认为这也会丢失上下文,因为即使使用这种方法我也无法定义

关于如何实现这一点的任何想法..是否可以使用 v 1.2 实现?如果可以通过创建自定义模态上下文来实现,那么有人可以提供一些关于如何为新窗口定义 addContext 函数的指针。

【问题讨论】:

  • 我的愚蠢无止境!!正如 Rainer 在他的第三次编辑 win =window.open 中指出的那样; win.targetwinvariable=value 工作得很好...不需要任何复杂的方法.. 2 天就完事了!!

标签: requirejs durandal


【解决方案1】:

通过使用window.open,可以创建一个与第一个 SPA 无关的#/viewname SPA 的独立实例。如果您真的必须打开一个新窗口,那么您需要寻找其他方式在窗口之间交换信息,例如localstorage

但你最好重新考虑需求,看看你是否不能用模态来实现目标。

根据评论编辑:这与 Durandal 失去上下文无关,它是关于 window.open 不在同一会话中打开。参见例如window.open doesn't open in same session

Edit2 作为替代方案,您可以在第二个窗口vm.activate 中使用参数#/viewname 直接从服务器(如果适用)或通过webstorage 检索数据,例如来自第一个浏览器的本地存储或会话存储。

Edit3 我做了一个快速测试,看看是否可以单独使用window.open 来完成。在 Firefox/Firebug 中测试。我仍然建议查看指向webstorage 的链接,以确保它可以跨浏览器工作。

转到http://dfiddle.github.io/dFiddle-1.2/#/,打开一个控制台并创建一个全局变量:

window.myVar = {complex: true};

创建一个新窗口

var myWindow = window.open('http://dfiddle.github.io/dFiddle-1.2/#/view-composition');

返回第一个控制台并在 myWindow 上创建一个属性 myvar

myWindow.myVar = myVar;

切换到第二个窗口的控制台并检查

myVar // output {complex: true}

我建议的替代方案使用您传递到第二个窗口的唯一哈希值,然后检索复杂数据(可以作为查询字符串添加)作为activate 回调的一部分。数据可以存储在服务器上或通过网络存储。

【讨论】:

  • 所以你说的是 Durandal 失去了上下文?我认为可以创建非模态窗口并保持模态上下文以便 durandal 意识到它是错误的吗?
  • 感谢您的回复雷纳。就我而言,会话无法发挥作用。打开一个新窗口并访问 javascript 变量值..这里不涉及服务器会话。并且 window.open 不会正常更改会话。在您的示例中确实如此,因为他们使用的是嵌入式控件而不是浏览器。在这个时刻,我唯一的解决办法似乎是通过改变 Durandal 的模态样式来模拟一个新窗口
  • 数据存储在 js var 的第一个窗口中,我只需要将其传递给第二个窗口。那么您是否建议将其作为查询字符串传递并在激活事件中获取它?如果你是我在原始帖子中提到的那样对我不起作用。
【解决方案2】:

Rainer 感谢您的帮助。以下代码将生成最大化的模态。在这个阶段,我将放弃这个解决方案并将我的数据作为激活传递给 showModal。它是默认模态上下文的精确副本,具有较小的 css 变化。但如果对某人有帮助,请发布它。

1. CSS

.modalHostMax {
    top: 0px;
    left: 0px;
    right: 0px;
    bottom: 0px;
    position: fixed;
    opacity: 0;

    -webkit-backface-visibility: hidden;

    -webkit-transition: opacity 0.1s linear; 
    -moz-transition: opacity 0.1s linear; 
    -o-transition: opacity 0.1s linear;
    transition: opacity 0.1s linear;
}
.modalMax {

    width: 100%;
    height: 100%;


}

2.新的模态上下文

   var addContext = function (contextName) {
            modalDialog.addContext(contextName, {
                blockoutOpacity: .2,
                removeDelay: 200,
                addHost: function (modal) {
                    var body = $('body');
                    var blockout = $('<div class="modalBlockout"></div>')
                        .css({ 'z-index': modalDialog.getNextZIndex(), 'opacity': this.blockoutOpacity })
                        .appendTo(body);

                    var host = $('<div class="modalHostMax"></div>')
                        .css({ 'z-index': modalDialog.getNextZIndex() })
                        .appendTo(body);

                    modal.host = host.get(0);
                    modal.blockout = blockout.get(0);

                    if (!modalDialog.isModalOpen()) {
                        modal.oldBodyMarginRight = $("body").css("margin-right");

                        var html = $("html");
                        var oldBodyOuterWidth = body.outerWidth(true);
                        var oldScrollTop = html.scrollTop();
                        $("html").css("overflow-y", "hidden");
                        var newBodyOuterWidth = $("body").outerWidth(true);
                        body.css("margin-right", (newBodyOuterWidth - oldBodyOuterWidth + parseInt(modal.oldBodyMarginRight)) + "px");
                        html.scrollTop(oldScrollTop); // necessary for Firefox
                        $("#simplemodal-overlay").css("width", newBodyOuterWidth + "px");


                    }


                },
                removeHost: function (modal) {
                    $(modal.host).css('opacity', 0);
                    $(modal.blockout).css('opacity', 0);

                    setTimeout(function () {
                        $(modal.host).remove();
                        $(modal.blockout).remove();
                    }, this.removeDelay);

                    if (!modalDialog.isModalOpen()) {
                        var html = $("html");
                        var oldScrollTop = html.scrollTop(); // necessary for Firefox.
                        html.css("overflow-y", "").scrollTop(oldScrollTop);
                        $("body").css("margin-right", modal.oldBodyMarginRight);
                    }
                },
                afterCompose: function (parent, newChild, settings) {

                    var $child = $(newChild);
                    var width = $child.width();
                    var height = $child.height();



                    $child.attr('class', 'modalMax');
                    $(settings.model.modal.host).css('opacity', 1);

                    if ($(newChild).hasClass('autoclose')) {
                        $(settings.model.modal.blockout).click(function () {
                            settings.model.modal.close();
                        });
                    }

                    $('.autofocus', newChild).each(function () {
                        $(this).focus();
                    });
                }
            });
        };

3.在您的目标视图中,确保容器最小高度设置为 $(document).height()

4.要使用通过调用 addContext('yourcontextname') 设置自定义上下文。然后创建您的模式 - app.showModal('viewname',{data},'yourcontextname')

【讨论】:

    猜你喜欢
    • 2014-06-18
    • 1970-01-01
    • 2014-01-27
    • 2022-01-07
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多