我正在尝试使用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对于最好的方法有任何直觉。任何帮助将不胜感激。
答案 0 :(得分:0)
我最终得到了这个工作。作为起点,我严重依赖使用example given in the docs的app-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>
的直接子元素,一旦我开始以聚合物方式考虑它,就允许这一点非常直接。