我正在尝试将整数绑定到String属性。确切地说,我试图将已发布的整数变量绑定到文本输入元素的value属性。
@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}}">
所以我切换到不使用绑定。有人可以建议使用绑定更好,更有效的解决方案吗?
答案 0 :(得分:2)
对于 Polymer 1.0.0 ,这对我来说很好用
创建可重用的行为或只将convertToNumeric()
添加到Polymer元素:
@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);
}
}
将行为应用于您的元素:
@PolymerRegister('app-element')
class AppElement extends PolymerElement with InputConverterBehavior {
AppElement.created() : super.created();
@property int intValue;
}
在元素的HTML中配置输入元素:
value
绑定到您的媒体资源:value="[[intValue]]"
,以便在媒体资源发生变化时更新输入元素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 :(得分:1)
这是针对 Polymer&lt; = 0.16 。对于 Polymer&gt; = 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
替代方法 使用Dart Polymer 1.0(也可以使用Dart Polymer 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>