1

我想编写一个将 Ember Input 扩展为数字输入的新组件。当此类的用户将他们的值绑定到number-input-component 的value属性时,他们应该只得到一个数字(或 NaN 表示无效值)。在 Ember 输入中,值具有属性绑定。

我在number-input-component上定义了一个名为“value”的计算属性,如下所示:

value:Ember.computed({
    get:function(key){
       let htmlValue = this.get('htmlvalue');
       return this.sanitize(htmlValue);
    },
    set:function (key, htmlvalue){
       this.set('htmlvalue', htmlvalue);

       if(this.get('onUpdate')) {
          this.get('onUpdate')(this.sanitize(htmlvalue));
       }
       return this.sanitize(htmlvalue);
    }
}),

它按预期工作,但不能在双向绑定中工作。(其实 DDAU 没问题,但是应该可以双向绑定。)

注意:我知道我可以提供另一个属性,例如“numericValue”(如图所示,以便用户可以将他们的值绑定到“numericValue”。但我不想将用户与valuenumericValue 混淆

更新:

键入该字段时,任何拼写错误都不应重置该值。例如,当用户尝试写入“123456789”并意外按下“12345678p”时,不应导致输入复位。当 value 无效时,既不显示错误消息也不重置 value 不是组件的责任。

你可以看到一个小提琴:Ember-Twiddle

4

3 回答 3

1

另一种方法是覆盖该_elementValueDidChange()方法。您可以通过 获取当前 DOM 值this.readDOMAttr('value'),进行清理,最后调用this.set('value', sanitizedValue). 这就是 Ember 在内部更改value属性的方式。

于 2016-04-30T13:19:22.350 回答
0

您可以编写属性的观察者,value并在更改时将其替换为经过清理的版本:

valueWatcher() {
    this.set('value' this.sanitize(this.get('value')));
}.observes('value')

当观察者修改其观察的属性时,Ember 将阻止竞争条件。

于 2016-04-29T14:55:08.277 回答
0

我找到了使用_elementDidChange@jcbvm 解决方案中建议的解决方案。还要重写attributeBindings 来管理屏幕值。

这里是:

import Ember from 'ember';

export default Ember.TextField.extend({
  type:'text',//hey! this is text!

  init(){
    this._super(...arguments);
    let arr = this.get('attributeBindings');
    arr.removeObject('value');
    arr.pushObject('val:value');
  },

  val: Ember.computed('domValue', 'value', function() {
    let value = this.get('value');
    //detect whether the update is trigger by dom or by users of this class:
    if(!Number.isNaN(value) && this.sanitize(this.get('domValue')) !== value){
      return value;
    }
    return this.get('domValue');
  }),

  _elementValueDidChange(){
    let domValue = this.readDOMAttr('value');
    let value = this.sanitize(domValue);
    if(this.sanitize(this.get('domValue')) !== value){
        this.set('domValue', domValue);      
    }
    this.set('value', value);
  },


  sanitize:function(value){
    if(value === ''){
      return Number.NaN;
    }
    return Number(value);
  }
});

使用的原因type=text是 html5 数字输入的净化算法。input type=number组件为 Chrome、Firefox 和 Edge(不是 IE)上的无效值返回空字符串。来自 W3C的清理参考。

此解决方案的缺点:

  • 覆盖_elementDidChange
  • 修改属性绑定。(也许父类取决于这个值。)
于 2016-05-01T07:04:29.180 回答