true example enablev2 databindingutil databinding data compiler data-binding binding filter dart dart-polymer

data binding - example - Dardo de polímero: valor entero de unión de datos al atributo de cadena



data binding v2 (2)

Para Polymer 1.0.0 esto funcionó bien para mí

Cree un comportamiento reutilizable o simplemente agregue el convertToNumeric() a su elemento de polímero:

@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); } }

Aplica el comportamiento a tu elemento:

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

En HTML de su elemento, configure el elemento de entrada:

  • vincular value a su propiedad: value="[[intValue]]" por lo que el elemento de entrada se actualiza cuando cambia la propiedad
  • configurar notificaciones de eventos para llamar al convertidor cuando el valor cambie on-input="convertToNumeric" notify-path="intValue" donde intValue es el nombre de la propiedad para actualizar con el valor numérico.

<!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>

Un enfoque alternativo

Crea una propiedad como getter / setter:

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

Crea un comportamiento o agrega la función directamente a tu elemento

@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); } }

De esta forma puede usar el mismo marcado que para los campos de entrada de texto

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

o si desea retrasar la actualización de la propiedad hasta que se deje el campo de entrada

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

Estoy intentando vincular un entero a un atributo de Cadena. Para decir exactamente, estoy intentando vincular una variable entera publicada al atributo de valor del elemento de entrada de texto.

@published int data = 0;

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

Obviamente, una referencia de String se almacena en lo que se supone que es un número entero.

Intenté utilizar el filtro para resolver este problema, pero aún así pude hacer que funcionara:

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}}">

Así que cambié a no usar enlace para esto. ¿Alguien puede sugerir una solución mejor y más eficiente mediante el enlace?


Esto es para Polímero <= 0.16 . Para Polymer> = 1.0 vea mi otra respuesta.

Los atributos HTML almacenan solo valores de cadena. Lo que podría hacer es usar un getter / setter para enlazar y analizar cuando se establece el valor.

@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; } }

o use un transformador o expresiones de polímeros personalizadas
como se explica en la entrada de polímero dart vinculante propiedades int

Aproximación alternativa utiliza Dart Polymer 1.0 (también es posible con 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>