2015-06-14 12 views
11

-Code

das folgende Polymer benutzerdefinierte Element Bedenken Sie:Polymer 1.0: Zwei-Wege-Bindungen mit Eingabeelementen

<dom-module id="test-element"> 

<template> 
    <input type="text" value="{{value}}"> 
    <button>Reset</button> 
</template> 

<script> 
Polymer({ 
    is: 'test-element', 
    properties: { 
     'value': { 
      type: String, 
      reflectToAttribute: true, 
      notify: true, 
      value: null 
     } 
    } 
}); 
</script> 

</dom-module> 

ich dieses benutzerdefinierte Element in meiner index.html wie folgt verwenden:

<html> 
<head> 
    <script type="text/javascript" src="bower_components/webcomponentsjs/webcomponents-lite.min.js"></script> 
    <link rel="import" href="test-element.html"> 
    <title>Test App</title> 
</head> 
<body> 
    <test-element value="test"></test-element> 
</body> 
</html> 

Frage

Ich glaube, ich habe die value Eigenschaft als eine Zwei-Wege-Bindung (notify: true) erklärt; Wenn ich jedoch auf die Eingabe klicke und einen Text eintippe (z. B. "foo"), wird sie nicht im Modell wiedergegeben (d. h. ein Aufruf an document.querySelector('test-element').value gibt den Wert zurück, den ich in index.html, "test", eingegeben habe). Interessanterweise ändert sich das value Attribut der Eingabe korrekt, aber die value -Eigenschaft meines Testelements nicht. Was vermisse ich?

Ich sollte auch beachten, dass ein Anruf an document.querySelector('test-element').setAttribute('value', 'bar') funktioniert ordnungsgemäß.

Antwort

27

Bitte beachten Sie, dass die Felder notify und reflectToAttribute auf der value Eigenschaft sagen, wie es auf seine Eltern nicht über die Bindung an ein Kind reagieren soll.

IOW bedeutet notify: truevalue Zweiweg-bindbare vom außen, von innen nicht zu machen. reflectToAttribute: true weist Polymer an, bei jeder Änderung value in ein Attribut zu schreiben (nicht gut für die Leistung).

Wenn Sie eine Bindung wie <x-element foo="{{value}}"> tun, dann ist es x-Element, die, wenn foo ist Zwei-Wege-bindable entscheidet.

Native Elemente wie input verfügen nicht über integrierte bidirektionale Bindungsunterstützung. Verwenden Sie stattdessen die Event-Observer-Syntax von Polymer zur bidirektionalen Bindung an eine Eingabe. So ähnlich <input value="{{value::change}}">.

Dies sagt Polymer, this.value von input.value zu aktualisieren, immer wenn die input ein change Ereignis auslöst.

+0

Danke. Die Unterscheidung von Innen und Außen macht jetzt Sinn für mich. Ich habe eine Änderung angefordert, indem ich einen Link zur Dokumentation hinzugefügt habe. –

+0

Ich möchte nur eine Nuance [Scott Miles] (http://stackoverflow.com/users/2192324/scott-miles) darauf hinweisen, dass das 'readOnly'-Feld in der Property-Deklaration nicht nur die Eigenschaften der Property bestimmt Verhalten in Bezug auf Elemente außerhalb des lokalen DOM, aber auch Elemente innerhalb des lokalen DOM. IOW, wenn ich eine Eigenschaft als schreibgeschützt festlegen, ist es schreibgeschützt für sowohl Kinder als auch Vorfahren. –

+0

Nur um klar zu sein, das bedeutet nicht, dass schreibgeschützte Eigenschaften niemals modifizierbar sind; Eine schreibgeschützte Eigenschaft ist über eine spezielle Setter-Methode modifizierbar, aber soweit ich sehen kann, ist dies nicht durch die Verwendung der Datenbindungs-API möglich. –

12

Sie müssen dies ändern:

<input type="text" value="{{value}}"> 

in

<input type="text" value="{{value::input}}"> 

versuchen here. Dies bedeutet, dass Polymer auf die Ereignisse des Inputs hört. Erklärt here (nicht sehr klar IMO).

+1

Sie haben Recht, ist irgendwie in der Docs irgendwo begraben; Ich habe die obige Antwort mit einem Link zu den Dokumenten bearbeitet (die darauf warten, überprüft zu werden), aber ich füge sie auch hier ein, damit sie für jeden leicht zu finden ist: https://www.polymer-project.org/ 1.0/docs/devguide/data-binding.html # Zweiwege-nativ –

0

Wie von Andrey und Scott Miles erwähnt, werden beide Lösungen funktionieren, um 2-way-bind mit einem nativen HTML-Eingabefeld zu erhalten.

<input type="text" value="{{value::input}}">

<input type="text" value="{{value::change}}">

Mit einem wichtigen Unterschied:

:: Änderung wird nur ausgelöst, wenn das Textfeld gedrückt wird, konzentrieren oder geben Sie verliert.

:: Eingang wird bei jedem Tastendruck ausgelöst.