使用Polymer构建列表的动态列表

时间:2016-07-30 07:17:02

标签: polymer

我正在尝试使用Polymer,并且正在努力弄清楚如何以Polymer-y方式创建我的系统。

我想要一个左侧导航栏(左侧的一列),as shown in the example app docs。出于解释的目的,左侧导航栏显示人员列表,主要内容窗口显示他们拥有的书籍列表。选择某人后,应更新主要内容窗口以仅显示该人的书籍。

两个列表都应该通过网络查询动态填充,并且可以通过刷新按钮重新填充。看起来这可能会使我绑定数据的方式变得复杂,因为这些函数不能只存在于shadowdom中,因为导航栏和内容列表需要能够进行通信。

从我查看Polymer的那天起,导航栏(人员列表)似乎是<iron-selector>的自然候选者。书籍列表听起来像<iron-list>。然而,我需要有几个图书清单实例 - 每个人一个。

我是否应该为此创建<book-list>自定义元素,可能在模板中使用<iron-list>?是否可以直接创建这些<book-list>元素以响应<iron-selector>中的选择,因为在查询图书所有者之前我不知道如何创建它们?有关如何做到这一点的任何指示?

这听起来像是一个非常基本的用例,但我仍然不太了解Polymer对于最好的方法有任何直觉。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我最终得到了这个工作。作为起点,我严重依赖使用example given in the docsapp-drawer-template

正如上述评论者的建议,使用路由器最终成为答案的一部分。令我困惑的是,我不确定如何动态更新该示例中使用的<iron-selector>以及<iron-pages>。我希望两者都代表相同的用户列表。我如何保持这些同步等?

我最终得到了三个自定义元素。其中两个是<iron-selector><iron-pages>周围的薄包裹。第三个是<user-provider>元素。 <user-provider>的作用是执行用户列表的请求,并将结果公开为其他两个元素可以与之交互的变量。

<user-provider>只有一个刷新按钮。它有一个名为users的{​​{1}}类型的属性。在Array生命周期回调中,为了响应单击刷新按钮,它会更新用户列表。请注意,ready()reflectToAttribute都设置为true,确保它确实可以将列表提供给其他元素。精简版本如下所示:

notify

我的<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> 元素将数组作为参数。让我感到困惑的是,我没有意识到在<user-selector>内部使用dom-repeat模板是多么简单。我以为我必须用<iron-selector>或其他东西包装重复,此时<div>将停止工作。使用<iron-selector>,我甚至可以使用我的特殊dom-repeat元素并将其始终保持在列表的底部。 settings变量对应于所选元素。

incoming

<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>的精简包装。它与<iron-pages>一起使用,以更新应用主要部分中显示的内容。

<user-selector>

最后,我的<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> 元素将它们连接在一起。

<my-app>

特别注意<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> 负责获取用户列表并仅通过变量公开它的方式,允许其他两个元素通过基本数据绑定获取数据。与<user-provider>元素一起作为dom-repeat<iron-selector>的直接子元素,一旦我开始以聚合物方式考虑它,就允许这一点非常直接。