Как переопределить родительское свойство в ember.js? (В частности, поведение ввода чисел)
Я хочу написать новый компонент, который расширяет Ember Input как ввод числа. Когда пользователи этого класса связывают свои значения с value
свойство number-input-component, они должны получать только число (или NaN для недопустимых значений). В Ember Input значение имеет привязку атрибута.
Я определил вычисляемое свойство с именем "value" для number-input-component следующим образом:
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". Но я не хочу путать пользователей со значением и numericValue.
ОБНОВИТЬ:
При вводе в поле любая опечатка не должна сбрасывать значение. Например, когда пользователь пытается написать "123456789" и случайно нажать "12345678p", это не должно вызывать сброс ввода. Ни отображение сообщения об ошибке, ни сброс значения не являются обязанностью компонента, если значение недопустимо.
Вы можете увидеть скрипку: Ember-Twiddle
3 ответа
Другим способом было бы перезаписать _elementValueDidChange()
метод. Вы можете получить текущее значение DOM, this.readDOMAttr('value')
Занимайтесь дезинфекцией и наконец звоните this.set('value', sanitizedValue)
, Вот как Эмбер внутренне меняет value
имущество.
Вы можете написать наблюдателя value
свойство и когда оно изменено, замените его очищенной версией:
valueWatcher() {
this.set('value' this.sanitize(this.get('value')));
}.observes('value')
Ember предотвратит состояние гонки, когда наблюдатель изменяет свойство, за которым он наблюдает.
Я нашел решение, используя _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
- Изменяет attributeBindings. (Возможно, родительские классы зависят от этого значения.)