灰色输入散焦清除模型值

时间:2014-12-11 03:47:17

标签: ember.js input

我有一个带有文本输入的ember模板和一个绑定到相同值的select视图。

{{input value=myValue}}
{{view "select" 
    content=myOptions 
    value=myValue 
    optionLabelPath="content.name" 
    optionValuePath="content.id"}}

我提供模型数据来支持这些选项

window.App = Ember.Application.create();

App.IndexRoute = Ember.Route.extend({
    model: function() { 
        return {
            myValue: 2,
            myOptions: [
                { name: 'a', id: 1 }, 
                { name: 'b', id: 2 },
                { name: 'c', id: 3 },
            ]
        }
    },
});

我为它创造了一个小提琴here

该值最初显示正常。但是,如果我对输入框进行聚焦,然后按箭头键或通过单击输入框取消对焦,则该值消失(输入框变为空白,选择框未显示选择的值)。

这个问题发生在一个更大的项目中,但上面的代码是我已经提炼出它的本质。似乎删除选择视图会使问题消失。我搜索过但找不到任何材料,说明为什么会发生这种情况。

我的问题是:为什么我会看到这种行为,我应该采用不同的方式吗?

2 个答案:

答案 0 :(得分:0)

我根本不能说出这种行为的原因。有一些关于Ember的select帮助器的讨论,特别是使用valueBinding和selectionBinding,值得一看(以及一个开放的bug):

https://github.com/emberjs/data/issues/82

https://github.com/emberjs/ember.js/issues/482

也就是说,将输入和选择绑定到同一个值似乎是一种奇怪的交互。虽然这不是你理想的答案(或我的答案),但是可以与一些观察者一起解决它并使用中间事件来进行链接:

window.App = Ember.Application.create();
App.SomeType = Ember.Object.extend({
    myValue: null,
    myObj: null,
    objChanged: function() {
        var o = this.get('myObj');
        if(!o) {
            return;
        }
        this.set('myValue', o.id);
    }.observes('myObj'),
    valChanged: function() {
        this.set('myObj', this.get('myOptions')[this.get('myValue')-1]);
    }.observes('myValue'),
    myOptions: null,
});
App.IndexRoute = Ember.Route.extend({
    model: function() { 
        var o = App.SomeType.create({
            myValue: 2,
            myOptions: [
                { name: 'a', id: 1 }, 
                { name: 'b', id: 2 },
                { name: 'c', id: 3 },
             ],
            });
            o.set('myObj', o.get('myOptions')[1]);
            return o;
        },
    }
);

HTML:

<script type="text/x-handlebars" data-template-name="index">
    <h1>Test</h1>
    {{input valueBinding=myValue}}
    {{view "select" 
        contentBinding=myOptions 
        selectionBinding=myObj
        optionLabelPath="content.name"}}
</script>

我在你的小提琴中试过它,它似乎运作正常。它只是将该值与Ember的手直接绑定在一起。这种复杂/间接绑定似乎有问题。

答案 1 :(得分:0)

我想与其他看到这个问题的人分享我最终的解决方案。

首先,我使用Ember Data来定义我的模型,并使用fixture来定义示例值:

App.MyOption = DS.Model.extend({
    name: DS.attr('name')
});

App.MyOption.FIXTURES = [
    { name: 'a', id: 1 }, 
    { name: 'b', id: 2 },
    { name: 'c', id: 3 },
];

App.MyModel = DS.Model.extend({
    myValue: DS.belongsTo('myOption')
});

App.MyModel.FIXTURES = [
    { 
        id: 1,
        myValue: 2
    }
];

在模型myValue中不是DS.attr('number'),而是belongsTo,这意味着当Ember数据加载灯具(或者可能是任何服务器数据)时,它会转换{ {1}}表示值(myValue: 2)的实际对象。因此,Ember Data处理ID到对象的映射,而不是将ID暴露给模板(在这方面似乎有错误)。

然后当我们在路线中加载模型时,我们使用Ember Data从商店(在这种情况下是我们的灯具)进行加载:

{ name: 'b', id: '2'}

现在在模板中,我们使用App.IndexRoute = Ember.Route.extend({ model: function() { return Ember.RSVP.hash({ myModel: this.store.find('myModel', 1), myOptions: this.store.find('myOption') }); }, }); 按照Carl的建议,将myValue绑定为对象而不是ID:

selectionBinding

Here is a fiddle一起显示解决方案。

注意:此解决方案在编辑文本输入的含义方面有不同的行为。以前,这是一种手动更改选择对象的方法,而现在它是一种更改当前所选对象名称的方法。在我的特殊情况下,这不是一个问题,但在你的问题中可能是这样。