使用 jquery ui 对话框时,Ember 中的双向绑定中断

Two way binding breaks in Ember when using a jquery ui dialog

本文关键字:绑定 中断 Ember ui jquery 对话框 使用      更新时间:2023-09-26

这是我的路线:

ExtractCreator.Router.map(function () {
    this.route('filter', { path: '/' }, function () {
        this.route('geog_levels');
    });
});

这是我创建jquery UI弹出窗口的观点:

ExtractCreator.FilterGeogLevelsView = Ember.View.extend({
didInsertElement : function(){
    var controller = this.controller;
    $('#filter-dialog').dialog({
        modal:true,
        stack: false,
        title: "Geogography Levels Filter",
        close: function(e,ui) {
            controller.transitionToRoute('filter');
        },
    }).dialog("moveToTop");
}
});

和模板:

      {{#each geog_level_group in model}}
            <h3>{{geog_level_group.label}}</h3>
            {{#each geog_level_filter in geog_level_group.geog_level_filters}}
            <div {{bind-attr class="geog_level_filter.disabled?:disabled"}}>
                <label>{{geog_level_filter.label}} - {{geog_level_filter.id}}</label> 
                {{input type="text" value=geog_level_filter.label }}
            </div>
            {{/each}}
        {{/each}}
我在

模板中将输入绑定到我的模型,但是每当我在输入字段中键入任何内容时,它都不会更新页面上的其他任何位置,也不会在我的(chrome)余烬检查器的模型视图中显示为已更新。

如果我从余烬检查器手动更改值,那么它会在弹出窗口中正确更新。

如果我将其从弹出窗口中取出(或只是删除弹出代码),那么一切都会正确绑定,并且当我更改输入值时标签将更新。

如何从对话框内部获得正确的绑定行为?

好吧,我曾经遇到过同样的奇怪行为,问题可能是由于带有子视图的 didInsertElement。(是的,当您使用每个视图和余烬{{input}}时,您如何拥有子视图)。

可以解决您的问题的一种方法是在 ember 完成后运行您的模态以渲染队列中的所有内容。您可以通过修改代码来实现这一点,如下所示:

didInsertElement : function(){
var controller = this.controller;
Ember.run.scheduleOnce('afterRender', this ,function(){
    $('#filter-dialog').dialog({
    modal:true,
    stack: false,
    title: "Geogography Levels Filter",
    close: function(e,ui) {
        controller.transitionToRoute('filter');
    },}).dialog("moveToTop");
 });
}

事实证明,绑定没有发生的原因是 jQuery-ui 对话框函数将"#filter-dialog"元素附加到 body 标签中,但在创建我的 Ember 应用程序时,我使用"rootElement"选项将 Ember 的范围限制为另一个div,ID 为"extract-creator"。

我的应用程序创建代码:

ExtractCreator = Ember.Application.create({
  rootElement: '#extract-creator'
});

在创建对话框时使用 appendTo 选项,我可以将其保留在 Ember 应用程序的范围内:

ExtractCreator.FilterGeogLevelsView = Ember.View.extend({
didInsertElement : function(){
    var controller = this.controller;
    $('#filter-dialog').dialog({
        modal:true,
        stack: false,
        title: "Geogography Levels Filter",
        appendTo: "#extract-creator",
        close: function(e,ui) {
            controller.transitionToRoute('filter');
        },
    }).dialog("moveToTop");
}
});

另一种解决方案是从 Ember create 选项哈希中删除"rootElement"行,使其默认为 body 标签。

特别感谢Buck Doyle在评论中发布了一个有效的JSBin。