Ember.js:如何在自定义组件上绑定模型属性

时间:2013-06-15 16:19:44

标签: data-binding ember.js datepicker

我想在表单中集成日期选择器。所以我创建了一个这样的自定义DateTimePickerView:

App.DateTimePickerView = Em.View.extend
  templateName: 'datetimepicker'
  didInsertElement: ->
    self = this
    onChangeDate = (ev) ->
      self.set "value", moment.utc(ev.date).format("dd/MM/yyyy hh:mm")
    @$('.datetimepicker').datetimepicker(language: 'fr', format: 'dd/mm/yyyy hh:ii').on "changeDate", onChangeDate

以下是模板:

<script type="text/x-handlebars" data-template-name="datetimepicker" >
  <input type="text" class="datetimepicker" readonly>
</script>

在我的表单中,我想将此组件绑定到我的模型的属性(我正在使用RestAdapter):

<script type="text/x-handlebars" id="post/_edit">
  <p>{{view Ember.TextField valueBinding='title'}}</p>
  <p>{{view App.DateTimePickerView valueBinding='date'}}</p>
</script>

一切都在表现得很好:DateTimePicker很好地显示,并在输入内设置值。 但是有效绑定存在问题:当我发送表单时,post param“date”(对应于属性)为null。

当我查看生成的html代码时,我可以看到以下内容:

<p>
  <input id="ember393" class="ember-view ember-text-field" type="text" value="Event 1">
</p>
<div id="ember403" class="ember-view">
  <input type="text" class="datetimepicker" readonly="">
</div>

我不是全局余烬结构的专家,但我想id元素对绑定很重要。在这种情况下,对于我的组件,ember id被放入我的组件的容器而不是包含该值的输入。所以我猜问题就在这里。

那么正确的方法是什么呢?

我刚刚创建了一个有效的jsfiddle here;我们可以看到标题字段中的修改被考虑在内,而不是DateTimePickerView组件中的修改。

2 个答案:

答案 0 :(得分:1)

我想问题在于你在哪里试图收听未被捕获的 datetimepicker 触发的事件,因此没有设置模型值。

为了使事情更加稳固,您应该在doneEditing函数中获取 datetimepicker 当前日期值,就在将模型保存回商店之前。

让我在代码中显示我的意思:

window.App.EventController = Ember.ObjectController.extend(
  ...

  doneEditing: ->
    // relevant code line
    @get("model").set("date_begin", $('.datetimepicker').data('date'))
    @set "isEditing", false
    @get("store").commit()
  ...
)

在这里你的(工作)jsfiddle

希望有所帮助

修改

阅读完评论后,我修改了 datetimepicker 模板中的输入字段。在调用edit时,请参阅here an updated jsfiddle并在编辑开始时初始化 datetimepicker 的输入字段。

...
edit: ->
  @set "isEditing", true
  startDate = @get("model").get("date_begin")
  @$(".datetimepicker").data({date: startDate}).datetimepicker("update")
...

您现在可以安全地删除onDateChange功能,并分别执行初始化并保存在editdoneEditing内,应用格式或其他内容。

修改2

阅读您的上一条评论,这就是您在customEvents注册App.DateTimePickerView的方式:

  ...
  customEvents: {
    changedate: "changeDate"
  }
  ...
这样,Ember就会知道你的自定义事件。您可以注册所需的任何事件,但请注意,keyname是小写的,值必须具有事件名称才能收听camelcased。有关自定义活动的更多信息,请参阅here

请在此处查看已注册changeDate自定义事件的其他update jsfiddle

答案 1 :(得分:1)

我在使用moment.js库时最终解决了这个问题。 使用自定义datetimepickerview的绑定过程,一切正常。

这是一个有效的jsfiddle:here

相关代码在这里:

window.App.DateTimePickerView = Ember.View.extend(
  templateName: 'datetimepicker'
  didInsertElement: ->
    #this test is important and was the problem
    if @.get 'value' 
      @$('input').val moment.utc(@.get 'value').format('LLL')
    onChangeDate = (ev) =>
      date = moment.utc(ev.date).format('LLL')
      @.set "value", date
    @$('.datetimepicker').datetimepicker(format: 'dd/MM/yyyy', pickTime: false).on "changeDate", onChangeDate
)