2014-09-01 47 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>