2016-07-30 15 views
0

I Polymer zu verwenden, ich versuche, und ich kämpfen, um herauszufinden, wie mein System in einer Polymer-y Art und Weise zu erstellen.Constructing dynamische Listen von Listen mit Polymer

Ich möchte eine linke Navigationsleiste (eine Spalte auf der linken Seite), as shown in the example app docs. Für die Zwecke der Erklärung zeigt die linke Navigationsleiste eine Liste von Personen und das Hauptinhaltsfenster zeigt eine Liste von Büchern, deren Eigentümer sie sind. Wenn eine Person ausgewählt ist, sollte das Hauptinhaltsfenster aktualisiert werden, um nur die Bücher dieser Person anzuzeigen.

Beide Listen sollten über eine Netzwerkabfrage dynamisch aufgefüllt werden und über eine Aktualisierungsschaltfläche erneut ausgefüllt werden können. Es scheint, als könnte dies die Art und Weise, wie ich Daten binde, komplizieren, da die Funktionen nicht einfach in einem Schattenbereich leben können, da die Navigationsleiste und die Inhaltslisten kommunizieren müssen.

Von dem Tag an, an dem ich mich mit Polymer beschäftigt habe, scheint die Navigationsleiste (Liste von Personen) ein natürlicher Kandidat für <iron-selector> zu sein. Die Liste der Bücher klingt wie <iron-list>. Ich muss jedoch mehrere Exemplare der Bücherliste haben - eine für jede Person.

Sollte ich ein <book-list> benutzerdefiniertes Element dafür erstellen, vielleicht mit <iron-list> in der Vorlage? Ist es einfach, diese <book-list> Elemente als Antwort auf Auswahlen in <iron-selector> zu erstellen, da ich nicht wissen, wie man sie vor der Abfrage für Buchbesitzer erstellen? Irgendwelche Hinweise, wie man das macht?

Das hört sich nach einem sehr einfachen Anwendungsfall an, aber ich weiß immer noch nicht genug über Polymer, um irgendwelche Intuitionen über die beste Methode zu haben. Jede Hilfe würde sehr geschätzt werden.

+0

Haben Sie darüber nachgedacht, vielleicht einen Router zu benutzen? Sie könnten Ihr Menü dynamisch in der Leiste mit den Benutzernamen erstellen. Wenn ein Benutzername angeklickt wird, navigiert das Tool zu '/ user/'. Sie haben dann ein Element in Ihrer Hauptansicht, das den Benutzer mit der 'USER_ID' anfordert und dann die mit diesem Benutzer verknüpften Bücher ausgeben kann. Ähnlich wie die [shop demo] (https://www.polymer-project.org/1.0/toolbox/case-study) funktioniert –

Antwort

0

Ich habe schließlich das funktioniert. Als Ausgangspunkt habe ich mich stark auf die example given in the docs gestützt, die app-drawer-template verwendet.

Wie oben von einem Kommentator vorgeschlagen, einen Router als Teil der Antwort endete. Was mich verwirrte war, dass ich sicher bin, wie man sowohl das in diesem Beispiel verwendete <iron-selector> als auch das <iron-pages> dynamisch aktualisiert. Ich wollte beide die gleiche Benutzerliste darstellen. Wie würde ich diese synchronisieren, usw.?

Ich endete mit drei benutzerdefinierten Elementen. Zwei waren dünne Umhüllungen um <iron-selector> und <iron-pages>. Das dritte war ein <user-provider> Element. Die Rolle von <user-provider> besteht darin, die Anforderung für die Benutzerliste auszuführen und das Ergebnis als Variable anzugeben, mit der die anderen beiden Elemente interagieren können.

<user-provider> hat nur eine Refresh-Button. Es hat eine Eigenschaft namens users vom Typ Array. Im Lebenszyklus-Callback ready() und als Reaktion auf das Klicken auf die Schaltfläche Aktualisieren aktualisiert es die Liste der Benutzer. Beachten Sie, dass reflectToAttribute und notify beide auf "true" gesetzt sind, um sicherzustellen, dass die Liste tatsächlich für die anderen Elemente bereitgestellt werden kann. Eine abgespeckte Version ist unten dargestellt:

<dom-module id="user-provider"> 
    <template> 
    <style> 
     :host { 
     display: block; 
     box-sizing: border-box; 
    </style> 
    <paper-fab icon="refresh" on-tap="refresh"></paper-fab> 
    </template> 

    <script> 
    Polymer({ 
     is: 'user-provider', 
     properties: { 
     users: { 
      type: Array, 
      notify: true, 
      reflectToAttribute: true 
     } 
     }, 
     refresh: function() { 
     this.refreshUsers(); 
     }, 
     refreshUsers: function() { 
     var _this = this; 
     // in reality I require a browserify module here 
     window.getUsersViaPromise() 
      .then(retrievedUsers => { 
      _this.users = retrievedUsers; 
      }); 
     }, 
     // Element Lifecycle 
     ready: function() { 
     this.users = []; 
     this.refreshUsers(); 
     } 
    }); 
    </script> 
</dom-module> 

Mein <user-selector> Element nimmt ein Array als Argument. Die Sache, die mich hier stampfte, war, dass ich nicht wusste, wie einfach es war, eine dom-repeat Vorlage innerhalb einer <iron-selector> zu verwenden. Ich dachte, ich würde die Wiederholungen in eine <div> oder etwas wickeln müssen, zu welchem ​​Zeitpunkt die <iron-selector> würde aufhören zu arbeiten. Mit dom-repeat kann ich sogar mein spezielles settings Element verwenden und es immer am Ende der Liste halten. Die Variable incoming entspricht dem ausgewählten Element.

<dom-module id="user-selector"> 
    <template> 
    <style> 
     :host { 
     display: block; 
     --app-primary-color: #4285f4; 
     --app-secondary-color: black; 
     } 
    </style> 

    <iron-selector 
     selected="{{incoming}}" 
     attr-for-selected="name" 
     class="drawer-list" 
     role="navigation"> 

     <template is="dom-repeat" items="{{users}}"> 
     <a name="view{{index}}">{{item.instanceName}}</a> 
     </template> 

     <a name="settings">Settings</a> 

    </iron-selector> 

    </template> 

    <script> 
    Polymer({ 
     is: 'user-selector', 
     properties: { 
     incoming: { 
      type: String, 
      reflectToAttribute: true, 
      notify: true 
     }, 
     users: { 
      type: Array, 
      reflectToAttribute: true 
     }, 
     } 
    }); 
    </script> 
</dom-module> 

<user-pages> ist eine dünne Hülle um <iron-pages>. Es funktioniert zusammen mit <user-selector>, um den Inhalt im Hauptteil der App zu aktualisieren.

<dom-module id="user-pages"> 
    <template> 
    <style> 
     :host { 
     display: block; 
     box-sizing: border-box; 
     } 
    </style> 

    <iron-pages role="main" selected="{{incoming}}" attr-for-selected="name"> 

     <template is="dom-repeat" items="{{users}}"> 
     <user-summary 
      name="view{{index}}" 
      username="{{item.userName}}"> 
     </user-summary> 
     </template> 

     <settings-view name="settings"></settings-view> 

    </iron-pages> 

    </template> 

    <script> 
    Polymer({ 
     is: 'user-pages', 

     properties: { 
     users: Array, 
     incoming: { 
      type: String, 
      reflectToAttribute: true, 
      notify: true 
     }, 
     } 
    }); 
    </script> 
</dom-module> 

Und schließlich lotet es mein <my-app> Element alle zusammen.

<dom-module id="my-app"> 
    <template> 
    <style> 
     :host { 
     display: block; 
     --app-primary-color: #4285f4; 
     --app-secondary-color: black; 
     } 

     app-header { 
     background-color: var(--app-primary-color); 
     color: #fff; 
     } 
     app-header paper-icon-button { 
     --paper-icon-button-ink-color: white; 
     } 

     .drawer-list { 
     margin: 0 20px; 
     } 
     .drawer-list a { 
     display: block; 
     padding: 0 16px; 
     line-height: 40px; 
     text-decoration: none; 
     color: var(--app-secondary-color); 
     } 
     .drawer-list a.iron-selected { 
     color: black; 
     font-weight: bold; 
     } 
     .drawer-list a.subroute { 
     padding-left: 32px; 
     } 
    </style> 

    <app-route 
     route="{{page}}" 
     data="{{routeData}}" 
     tail="{{subroute}}"></app-route> 

    <app-drawer-layout fullbleed> 

     <!-- Drawer content --> 
     <app-drawer> 
     <app-toolbar>My App</app-toolbar> 
     <start-app-button></start-app-button> 
     <user-provider users="{{retrievedUsers}}"></user-provider> 
     <user-selector incoming="{{page}}" users="{{retrievedUsers}}"> 
     </user-selector> 
     </app-drawer> 

     <!-- Main content --> 
     <app-header-layout has-scrolling-region> 

     <app-header condenses reveals effects="waterfall"> 
      <app-toolbar> 
      <paper-icon-button icon="menu" drawer-toggle></paper-icon-button> 
      <div title>My App</div> 
      </app-toolbar> 
     </app-header> 

     <user-pages 
      incoming="{{page}}" 
      users="{{retrievedUsers}}"> 
     </user-pages> 

     </app-header-layout> 

    </app-drawer-layout> 

    </template> 

    <script> 
    Polymer({ 
     is: 'my-app', 
     properties: { 
     page: { 
      type: String, 
      reflectToAttribute: true 
     }, 

     }, 
     observers: [ 
     '_routePageChanged(routeData.page)' 
     ], 
     _routePageChanged: function(page) { 
     this.page = page || 'view1'; 
     } 
    }); 
    </script> 
</dom-module> 

Hinweis insbesondere auf die Art und Weise, dass <user-provider> zum Erhalten der Liste von Benutzern verantwortlich ist und es nur über eine variable Belichtung, so dass die beiden anderen Elemente, die die Daten über grundlegende Datenbindung machen, zu erhalten. Das, zusammen mit den dom-repeat Elementen als unmittelbare Kinder von <iron-selector> und <iron-pages>, erlaubte dies ziemlich geradlinig zu sein, sobald ich anfing, es auf die Art Polymer zu denken.

Verwandte Themen