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

时间:2015-09-30 22:17:06

标签: javascript meteor bootbox

在我的第一个活动中,我将打开一个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为此。

但我不想破坏流星包中的模态,这是由另一个创建的。我尝试使用全局变量,我尝试使用api.export()。但它仍然无效。我也尝试过Sessions。

包图表/ LIB /客户端/ 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(...);

包图表/ LIB / package.js

api.export('bbox');

第二个包提供了一个typeahead-searchbox(sergeyt:typeahead)。通过在第一个包中创建模态,模板将加载到模态(helloludger:mbox)中。现在,用户可以通过预先搜索并选择一个项目。在选择之后,模态应该被`modal('hide')破坏。

包的搜索/ LIB /客户端/ events.js

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

包的搜索/ LIB /客户端/ 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;
        }
    }
});

4 个答案:

答案 0 :(得分: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');
    }
});

答案 1 :(得分:2)

不要这样做 - it violates software engineering principles.

您努力寻找解决方案的原因强烈暗示这不是构建应用程序的好方法。

  • 您希望packageMBox嵌入packageTypeAhead,这意味着packageMBox依赖于packageTypeAhead。

  • 您希望packageTypeAhead进入packageMBox并控制它,需要(感谢Gaelan)packageTypeAhead依赖于packageMBox。

这是双向耦合,即使你找到了让它工作的方法,你实现了什么?你有两个包,它们都不能独立使用(或者甚至没有正确测试)。

所以解决方案是:将两个包合并到一个包中

&#39; Package for everything&#39;是构建应用程序的好方法,但重要的是要考虑分割功能的方式和位置,这样就不会产生比开始时更多的问题。

答案 2 :(得分:1)

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

api.use('first-package')

只能从依赖项中导出。

Relevant Meteor docs

答案 3 :(得分: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;
        }
    }
});

理想情况下,您可以创建自己的第三个独立模块,以便在两个包之间进行通信,并将其注入两个包中。这样他们就没有耦合,可以共享状态。

在这个共享模块中,您只需要一个包含模态实例的setter和getter函数。我不熟悉流星,所以我不确定你会怎么做,但从你已经写过的内容来判断它应该是可能的。

如果您想要解决此问题,请添加评论。