2014-09-01 109 views
1

我想要绑定一个整数字符串属性。准确地说,我试图将已发布的整数变量绑定到文本输入元素的值属性。聚合物飞镖:数据绑定整数值字符串属性

@published int data = 0;

<input type="number" value="{{data}}"> 

显然,String的引用被存储在应该是一个整数。

我试图使用过滤器来解决这个问题,但还是没能得到它的工作:

int integerize(Object a) { 
    int ret = 0; 
    if (a is String) { 
    try { 
     ret = int.parse(a); 
    } on FormatException catch (e) { 
    } 
    } else if(a is int) { 
    ret = a; 
    } 
    return ret; 
} 

<input type="number" value="{{data | integerize}}"> 

所以我切换到不使用此绑定。有人可以建议使用绑定更好,更有效的解决方案吗?

回答

2

对于聚合物1.0.0这个工作对我罚款

创建一个可重复使用的行为,或者只是添加convertToNumeric()你聚合物元件:

@HtmlImport('app_element.html') 
library app_element; 
import 'dart:html' as dom; 
import 'package:web_components/web_components.dart' show HtmlImport; 
import 'package:polymer/polymer.dart'; 

@behavior 
abstract class InputConverterBehavior implements PolymerBase { 
    @reflectable 
    void convertToInt(dom.Event e, _) { 
    final input = (e.target as dom.NumberInputElement); 
    double value = input.valueAsNumber; 
    int intValue = 
     value == value.isInfinite || value.isNaN ? null : value.toInt(); 
    notifyPath(input.attributes['notify-path'], intValue); 
    } 
} 

将行为t Ø你的元素:

@PolymerRegister('app-element') 
class AppElement extends PolymerElement with InputConverterBehavior { 
    AppElement.created() : super.created(); 

    @property int intValue; 
} 

在你的元素的HTML配置输入元素:

  • 绑定value你的财产:value="[[intValue]]"所以当属性改变
  • 设置事件input元素被更新通知在值更改时调用转换器on-input="convertToNumeric" notify-path="intValue"其中intValue是使用数字值更新的属性的名称。
<!DOCTYPE html> 
<dom-module id='app-element'> 
    <template> 
    <style> 
     input:invalid { 
     border: 3px solid red; 
     } 
    </style> 
    <input type="number" value="[[intValue]]" 
      on-input="convertToInt" notify-path="intValue"> 

    <!-- a 2nd element just to demonstrate that 2-way-binding --> 
    <input type="number" value="[[intValue]]" 
      on-input="convertToInt" notify-path="intValue"> 
    </template> 
</dom-module> 

另一种方法

创建一个财产的getter/setter:

int _intValue; 
    @property int get intValue => _intValue; 
    @reflectable set intValue(value) => convertToInt(value, 'intValue'); 

创建一个行为或直接添加的功能,你的元素

@behavior 
abstract class InputConverterBehavior implements PolymerBase { 
    void convertToInt(value, String propertyPath) { 
    int result; 
    if (value == null) { 
     result = null; 
    } else if (value is String) { 
     double doubleValue = double.parse(value, (_) => double.NAN); 
     result = 
      doubleValue == doubleValue.isNaN ? null : doubleValue.toInt(); 
    } else if (value is int) { 
     result = value; 
    } else if (value is double) { 
     result = 
      value == value.isInfinite || value.isNaN ? null : value.toInt(); 
    } 
    set(propertyPath, result); 
    } 
} 

这样,您就可以使用相同的标记用于文本输入字段

<input type="number" value="{{intValue::input}}"> 

,或者如果你想拖延财产的更新,直到输入字段保留

<input type="number" value="{{intValue::change}}"> 
1

这是用于聚合物< = 0.16。对于聚合物> = 1.0看到我的其他答案。

HTML属性仅存储字符串值。你可以做的是在设置值时使用getter/setter进行绑定和解析。

@observable 
int data; 

@ComputedProperty('data') // haven't tried this but should work - see comments on http://japhr.blogspot.co.at/2014/08/whats-difference-between-attribute-and.html 
@observable 
get dataValue => data; 
set dataValue(val) { 
    if(val == null) { 
    data = 0; 
    } else if(val is num) { 
    data = val.toInt(); 
    } else if(val is String) { 
    data = num.parse(val, (v) => 0).toInt(); 
    } else { 
    data = 0; 
    } 
} 

,或者使用一个变压器或定制聚合物表达式
polymer dart input binding int properties

替代approache 使用达特聚合物1.0(也可能与达特聚合物0.16)

app_element解释.dart

@HtmlImport('app_element.html') 
library _template.web.app_element; 

import 'dart:html' as dom; 
import 'package:web_components/web_components.dart' show HtmlImport; 
import 'package:polymer/polymer.dart'; 

@PolymerRegister('app-element') 
class AppElement extends PolymerElement { 
    AppElement.created() : super.created(); 

    @property int intValue; 
    @property String stringValue; 

    @reflectable 
    valueInputHandler(dom.Event event, [_]) { 
    var input = (event.target as dom.NumberInputElement); 
    var value = input.valueAsNumber; 
    if (!value.isNaN && !value.isInfinite) { 
     set('intValue', value.toInt()); 
     input.setCustomValidity(''); 
    } else { 
     // just to get the `:invalid` pseudo-class for styling 
     input.setCustomValidity('Not a number.'); 
    } 
    } 
} 

app_element.html

<!DOCTYPE html> 
<dom-module id='app-element'> 
    <template> 
    <style> 
     input:invalid { 
     border: 3px solid red; 
     } 
    </style> 
    <input type="number" 
      value="{{stringValue::input}}" 
      on-input="valueInputHandler" > 
    <div>stringValue: <span>{{stringValue}}</span></div> 
    <div>intValue:<span>{{intValue}}</span></div> 
    </template> 
</dom-module>