使用带有`<input type =“number”/>`的ember-data数字属性

时间:2015-05-21 08:42:58

标签: ember.js casting ember-data

了解isDirty - 一个意外结果的简单情况

在我回答我的问题之前,有些情况。我有一个余烬数据项目

DEBUG: -------------------------------
DEBUG: Ember             : 1.11.1
DEBUG: Ember Data        : 1.0.0-beta.16.1
DEBUG: jQuery            : 1.11.2
DEBUG: Ember Simple Auth : 0.7.3
DEBUG: -------------------------------

Ember数据模型

我有一个包含一些字符串属性和一些数字属性的简单模型。这是我的app\models\simplemodel.js

import DS from "ember-data";

export default DS.Model.extend({
  code: DS.attr('string'),
  description: DS.attr('string'),
  a_number: DS.attr('number'),
  another_number: DS.attr('number'),
  related_stuff: DS.hasMany('someothermodel', {async: true})
});

带有绑定<input type="number">元素的把手模板

我有一个模板,我在其中使用绑定的<input type="number">元素设置数字参数。

<header>
  <h2>{{model.code}}</h2>
  <h2>{{textarea value=model.description placeholder="description"}}</h2>
</header>
<section>
  <p>
      <label>A number:&nbsp;</label>{{input type="number" value=model.a_number}}
      <label>Another number:&nbsp;</label>{{input type="number" value=model.another_number}}
    {{#if model.isDirty}}
      <button {{action 'save'}}>Save</button>
    {{/if}}
  </p>
</section>

问题/意外行为

当我更改<input type="number">元素的值时,保存按钮会按预期显示。但是,当我将值重置为原始值时,保留按钮仍然存在。即使值与原始值匹配,模型isDirty仍然为真。

可能的解释

现在,我知道<input>元素会将其内容存储为字符串而不是数字。据推测,当我更改绑定input的值时,它会将绑定模型属性设置为其值。可能是原始值是1,但是使用<input>元素我将值更改为"1"。但是,模型显式声明此属性为DS.attr('number')。实际上,当我保存模型时,它会尽职地将有效负载中的数字发送到服务器。

{"simplemodel":{"code":"34735337888888","description":"Some description","a_number":4,"another_number":5}}

这是预期的,ember-data处理与服务器的通信,并将DS.attr('number')属性转换为数字。所以我猜模型属性在发送到服务器之前的实际值仍然是一个字符串,因此模型isDirty

支持此功能的简单测试是,如果我将属性更改为a_number: DS.attr('string'),那么问题就会消失。使用字符串属性,当我更改输入元素时isDirty标志翻转,当我将输入返回到原始值时翻转。当然,这会将数据作为字符串发送到服务器。

问题

当将输入元素中的字符串与模型中的原始数字进行比较时,问题似乎是isDirty过度敏感。即使输入字段提供字符串,我能以某种方式将模型属性设置为数字吗?

可能的解决方案

我可以看到两种明显的方法来处理这个问题。

  1. 制作一个透明地将字符串转换为数字的输入元素的版本 - 我试过这个没有运气 - 可能是因为我不明白ember是如何工作的。
  2. 让模型自动将值转换为适当的类型。
  3. 我的本​​能是与1一起使用,2感觉更有可能产生意外行为。

    我的尝试

    我尝试生成一个组件,用于绑定到数字的所有输入元素。

    import Ember from 'ember';
    
    export default Ember.Component.extend({
        attributeBindings: ['value', 'type'],
        tagName: 'input',
        type: 'number',
        number: null,
    
        value: function() {
          var number = this.get('number');
          return number;
        }.property('number'),
    
        change: function() {
          var value = this.$().val();
          this.set('number', parseFloat(value));
        }
    });
    

    当我使用它时,即使我的组件的值发生了变化,也没有设置isDirty标志。无论如何,我不明白这一点,它改编自我一直用于日期字段的东西。我需要在这里做点什么吗?

0 个答案:

没有答案