关闭在另一个事件函数中创建的模态窗口

8
在我的第一个事件中,我将打开一个 mbox 对话框。mbox 是 bootbox 的一种扩展,用于显示模态窗口。我需要 mbox 使用另一个模板作为模态框内容。
因此,模态框将加载 createElement-Template 的内容。如果用户进行了一些输入更改,模态框应该被关闭。因此有函数 modal("hide")。但是由于 bbox 在第一个模板事件中设置,而关闭模态框将在第二个模板事件中完成,所以我遇到了关闭模态框的问题。 事件
Template.main.events({
    'submit form': function(event, template) {
        event.preventDefault();

        var bbox = mbox.dialog({
            title: 'title',
            message: Template.createElement
        });
    }
});

Template.createElement.events({
    'change input': function(event, template) {
        bbox.modal('hide');
    }
});

更新

以上问题使用了一个全局变量来解决。感谢Adam提供的帮助。

但是现在我想销毁一个meteor包中的模态框,这个包是由另一个创建的。我尝试使用全局变量和api.export(),但仍然无法解决问题。我还尝试使用Sessions。

package-graph/lib/client/graph.js

var bbox;
CanvasManager = {
    onShowAddToolTip (element) {
        bbox = mbox.dialog({ // <-- Create Modal
            title: "Title",
            message: Template.search, // <-- Loading Template search with just one input field with typeahead
        });
    },
}

CanvasManger.create(...);

package-graph/lib/package.js

api.export('bbox');

第二个包提供了一个类型提示搜索框(sergeyt:typeahead)。通过在第一个包中创建模态框,模板将会在模态框中加载(helloludger:mbox)。现在用户可以通过类型提示进行搜索并选择项目。选择后,应该通过 `modal('hide')` 销毁模态框。

package-search/lib/client/events.js

Template.searchMain.onRendered(function() {
    Meteor.typeahead.inject();
});

package-search/lib/client/helper.js

Template.search.helpers({ // <-- getting the data for the input typeahead
    searchData: function() {
        return [
            {
                name: 'cat1',
                valueKey: 'title',
                displayKey: 'title',
                header: '<h3 class="category-name">Category</h3>',
                template: 'searchResults',
                local: function() {
                    return Collection.find().fetch();
                }
            }
        ]
    },
    selected: function(event, suggestion) { // <-- by selecting an item, I can process the data and remove the modal
            // do something
            bbox.modal('hide'); // <!-- destroy modal
            return;
        }
    }
});

你能否也发布一下HTML代码?在Meteor中,你可以通过Template.instance()共享和访问模板实例上的状态对象。 - Jeroen Peeters
如果您在bbox前面刪除var,則應該可以跨文件訪問它。 請將“ var bbox;”更改為“ bbox = null;”嘗試一下。 - Jake Runzer
4个回答

8

bbox变量设为全局变量:

var bbox;
Template.main.events({
    'submit form': function(event, template) {
        event.preventDefault();

        bbox = mbox.dialog({
            title: 'title',
            message: Template.createElement
        });
    }
});

Template.createElement.events({
    'change input': function(event, template) {
        bbox && bbox.modal('hide');
    }
});

4
@user3142695 - 在这一点上,您无法保证bbox已被设置(它可能仍然是“未定义”的)。 bbox && doSomething()与说if(bbox) { doSomething() }相同,只是JavaScript的简写形式。 - Adam Jenkins
我尝试使用全局变量,在第一个示例中可以正常工作。但是在使用包的情况下,我遇到了同样的问题。我更新了帖子以使其更清晰,请查看一下。 - user3142695

2
不要这样做——它违反了软件工程原则。 你苦苦寻找解决方案的原因是这种结构并不好,这已经是一个很明显的提示。
  • 你想让 packageMBox 嵌入 packageTypeAhead,这意味着 packageMBox 依赖于 packageTypeAhead。

  • 同时你又想让 packageTypeAhead 接管 packageMBox,这需要(感谢 Gaelan)packageTypeAhead 依赖于 packageMBox。

这就是双向耦合,即使你找到了一种使其工作的方式,你取得了什么成果呢?你有两个包,都不能被独立使用(甚至无法进行正确的测试)。
所以解决方案是:将这两个包合并成一个包
万能的包”是一种很好的应用结构方式,但重要的是要考虑如何和在哪里拆分功能,以免引发更多问题。

1

确保第二个软件包依赖于第一个软件包:

api.use('first-package')

只有从依赖项中导出的内容可用。

相关 Meteor 文档


0

如果你要在全局变量上进行编程,那么你也可以在你的mbox上进行编程。

mbox.myModal = mbox.dialog({
  title: 'title',
  message: Template.createElement
});

然后在 package-search/lib/client/helper.js

Template.search.helpers({
    ...
    selected: function(event, suggestion) {
            mbox.myModal && mbox.myModal.modal('hide');
            mbox.myModal = null;
            return;
        }
    }
});

理想情况下,您应该创建自己的第三方独立模块,用于在两个软件包之间通信,并将其注入到两个软件包中。这样它们就没有耦合关系,可以共享状态。
在此共享模块中,您只需要一个设置器和获取器函数来保存您的模态实例。我不熟悉Meteor,所以不确定您要如何做到这一点,但根据您已经编写的内容,这应该是可能的。
如果您想要一起解决问题,请添加评论。

我想用这种方式来做。你能给我一些代码示例吗? - user3142695

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接