8

我需要使用 EmberJS 验证绑定到模型属性的表单文本字段。我希望用户只能输入有效的正数。

我知道 jQuery.isNumber(),但我不知道如何将它连接到字段。我尝试使用 Ember.computed(...) 在模型的属性上编写显式的 getter/setter 函数,但没有成功。

有没有类似于 WinForms onChanging() 事件的东西可以连接到?

4

4 回答 4

14

有很多方法可以做这种事情。在这里,我们可以使用绑定和观察者来完成此操作。

首先让我们创建一个总是返回一个数字的函数。

var onlyNumber = function(input) {
    return input.toString().replace(/[^\d.]/g, "");
};

使用它我们可以执行以下操作

App = Ember.Application.create();

App.person = Ember.Object.create({
    age: 42
});

App.NumberField = Ember.TextField.extend({
    valueBinding: Ember.Binding.from("App.person.age").transform(onlyNumber),

    _cleanValue: function() {
        this.set('value', onlyNumber(this.get('value')));
    }.observes('value')
});

1)我们正在创建一个绑定到 Person 的年龄,但是通过这个绑定的任何东西都只能是一个数字。有关更多详细信息,请参阅Ember.Binding到/从转换。

2)我们正在观察文本字段的值,并在它发生变化时将其设置为仅数字。如果用户输入“42a”,我们将立即将其设置回“42”。请注意,即使“42a”在文本输入中出现了短暂的一秒钟,由于我们的转换,它也无法通过绑定。

这是显示此示例的小提琴:http: //jsfiddle.net/nDBgC/

于 2012-05-22T04:39:17.860 回答
3

您可以keyDown在 TextField 上添加事件处理程序,请参阅http://jsfiddle.net/pangratz666/SKJfF/

App.NumberTextField = Ember.TextField.extend({
    // implementation of this function, see http://stackoverflow.com/a/995193/65542
    keyDown: function(event) {
        // Allow: backspace, delete, tab, escape, and enter
        if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || event.keyCode == 13 ||
        // Allow: Ctrl+A
        (event.keyCode == 65 && event.ctrlKey === true) ||
        // Allow: home, end, left, right
        (event.keyCode >= 35 && event.keyCode <= 39)) {
            // let it happen, don't do anything
            return;
        }
        else {
            // Ensure that it is a number and stop the keypress
            if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
                event.preventDefault();
            }
        }
    }
});​
于 2012-05-21T13:11:56.177 回答
1

代码(仅处理数字输入并允许绑定数字而不是字符串,如果需要):

App.NumberFieldComponent = Ember.TextField.extend({
  tagName: "input",
  type: "number",

  numericValue: function(key, value) {
    if (arguments.length === 1) {
      return parseFloat(this.get("value"));
    } else {
      return this.set("value", (value !== void 0 ? "" + value : ""));
    }
  }.property("value"),

  didInsertElement: function() {
    return this.$().keypress(function(key) {
      if ((key.charCode !== 46) && (key.charCode !== 45) && (key.charCode < 48 || key.charCode > 57)) {
        return false;
      }
    });
  }
});

模板:

{{number-field numericValue=someNumericProperty}}
于 2014-06-22T09:34:13.340 回答
0

这是最新 Ember 版本(Ember-cli 2.0)的更新答案(来自@neverfox)。它是用咖啡脚本编写的,并进行了一些修改以匹配 becomeFocus 示例(http://guides.emberjs.com/v1.10.0/cookbook/user_interface_and_interaction/focusing_a_textfield_after_its_been_inserted/

  1. 生成组件:

    ember g 组件编号字段

  2. 将蓝图代码 (app/components/number-field.coffee) 更改为

  `import Ember from 'ember'`
    
    NumberFieldComponent = Ember.Component.extend
        tagName: "input"
        type: "number"
    
    	numericValue: ( (key, value) ->
    		if arguments.length == 1
    			parseFloat(this.get('value'))
    		else
    			return this.set("value", (value? ? "" + value : ""))
    	).property('value')
    
    	assignFilter: ( ->
    		this.$().keypress (key) ->
    			if ((key.charCode != 46) && (key.charCode != 45) && (key.charCode < 48 || key.charCode > 57))
    				false
    	).on('didInsertElement')
          		
    
    `export default NumberFieldComponent`

于 2015-03-27T08:11:04.987 回答