2014-12-11 144 views
0

我有一个带有文本输入和select视图绑定到相同值的余烬模板。Ember输入焦点清除模型值

{{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

该值初始显示正常。但是,如果我关注输入框,然后按下箭头键或通过单击输入框将其取消焦点,则该值将消失(输入框变空白并且选择框不显示所选值)。

这个问题发生在一个更大的项目中,但上面的代码是我将它的精髓提炼成的。似乎删除选择视图使问题消失。我已经搜索,但无法找到任何材料,说明这可能发生的原因。

我的问题是:为什么我看到这种行为,我应该这样做吗?

回答

0

我不能说这种行为的原因。大约有Ember的选择帮手一些讨论,特别是与使用的ValueBinding的VS 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手中直接获得该价值。这种复杂/间接的绑定似乎很麻烦。

+0

所以,你说'selectionBinding'比'valueBinding'在这种情况下更好? 'selection'和'selectionBinding'之间有区别吗? – Mike 2014-12-11 09:39:09

+0

一般情况下,如果有可能从任何一方改变事物,请使用xBinding。也就是说,如果视图可能会修改该值并且希望将其反映到模型中,或者某些内容可能会更改该模型,并且您希望在视图中查看它。 – Carl 2014-12-11 13:43:02

+0

是的,在这种情况下,我选择了而不是价值,因为我不认为当前的实现与optionValuePath非常干净地工作。所以在这里我更愿意将视图的选择作为一个整体对象进行绑定,并将自己的价值置于正确的位置。 – Carl 2014-12-11 13:44:49

0

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

首先,我使用余烬数据来定义我的模型,并使用夹具来定义的示例值:

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,这意味着当灰烬数据加载灯具(或可能是任何服务器数据),它会将myValue: 2转换为代表该值的实际对象({ name: 'b', id: '2'})。所以Ember Data处理ID到对象的映射,而不是将ID暴露给模板(这在这方面似乎有错误)。

那么当我们在路由加载模型,我们用灰烬数据做从商店这种负载(在这种情况下,我们的灯具):

App.IndexRoute = Ember.Route.extend({ 
    model: function() { 
     return Ember.RSVP.hash({ 
      myModel: this.store.find('myModel', 1), 
      myOptions: this.store.find('myOption') 
     }); 
    }, 
}); 

现在在模板中,我们结合myValue为一个对象而不是ID,使用selectionBinding所推荐的卡尔:

{{input value=myModel.myValue.name}} 
{{view "select" 
    content=myOptions 
    selectionBinding=myModel.myValue 
    optionLabelPath="content.name"}} 

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

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