我正在尝试构建一个可重复使用的聚合物Web组件,该组件支持通过拖放核心列表重新排序项目。我想要的接口与core-list
基本相同<reorderable-list id="list" data="{{data}}" height="60">
<template>
<some-reorderable-element>
</some-reorderable-element>
</template>
</reorderable-list>
我目前的想法是,我希望每行包装如下
<a-container>
<draggable-member>
<some-reorderable-element>
</some-reorderable-element>
</draggable-member>
</a-container>
其中a-container
始终保持不变,且大小与行的大小完全相同,draggable-member
在a-container
拖动时附加到core-drag-drop
头像。当a-container
仍然存在时,这应该保持那里的行只有我希望的背景颜色。
我正在努力解决的问题是如何为每一行实例化上述结构。
我正走在像
这样的道路上<core-list-dart id="list" data="{{data}}" height="{{height}}">
<template>
<a-container>
<draggable-member id="member" draggable="true">
<content></content>
</draggable-member>
</a-container>
</template>
</core-list-dart>
不确定这是否朝着正确的方向发展。 Catch是core-list
仅用于实例化a-container
的副本。不知何故,我需要实例化draggable-member
的副本以及每行的用户提供的内容,但不确定如何最好地做到这一点,或者这是否是一个好方法。
修改
好好把我的头发拉了几个小时之后,我觉得我的答案就像编程一样
@CustomTag('reorderable-list')
class ReorderableList extends PolymerElement with Observable {
@published ObservableList data;
@published double height;
ReorderableList.created() : super.created() {
}
attached() {
final CoreList coreList = new Element.tag('core-list-dart');
coreList.data = data;
coreList.height = height;
final TemplateElement template = new Element.tag('template');
final MemberContainer mc = new Element.tag('member-container');
final ReorderableMember rm = new Element.tag('reorderable-member');
rm.children.addAll(children);
mc.append(rm);
template.content.append(mc);
coreList.append(template);
shadowRoot.append(coreList);
}
}
这几乎给了我想要的东西,但并不是因为我没有把东西放在阴影中。回到绘图板: - (
我以为我把它固定了,但现在看来ContentElement以神秘的方式运行。
当行项目使用<content></content>
时,当您从常规父级中分离组件并将其添加到头像时,此内容将消失。据推测,ContentElement动态工作,无法再找到关联的内容。我必须更好地了解它是如何工作的,看看我能不能解决它。
<link rel="import" href="../../../../packages/core_elements/core_style.html">
<link rel="import" href="../../../../packages/core_elements/core_drag_drop.html">
<core-style id="draggable-list-item" unresolved>
#row-container, #drag-container {
padding: none;
margin: none;
display: block;
}
#row-container {
border: solid 1px black;
}
}
</core-style>
<polymer-element name="draggable-list-item" on-drag-start="{{startDrag}}">
<template>
<core-style ref="draggable-list-item"></core-style>
<core-drag-drop></core-drag-drop>
<div id="row-container">
<drag-container id="drag-container">
<content></content>
</drag-container>
</div>
</template>
<script type="application/dart" src="draggable_list_item.dart"></script>
</polymer-element>
<polymer-element name="drag-container" draggable="true">
<template>
<style>
#foo {
border: solid 1px blue;
height: 100%;
width: 100%;
}
</style>
<div id="foo">
<p>Hola</p>
<content></content>
</div>
</template>
</polymer-element>
-
library ui.polymer.core.list.item.draggable;
import 'package:polymer/polymer.dart';
import 'dart:html';
import 'package:logging/logging.dart';
import 'dart:js';
Logger _log = new Logger('ui.polymer.core.item.draggable');
@CustomTag('draggable-list-item')
class DraggableListItem extends PolymerElement with Observable {
bool multi;
DraggableListItem.created() : super.created() {
_log.finer('DraggableListItem.created');
}
void startDrag(CustomEvent e, JsObject dragInfo) {
_log.finest('DraggableListItem dragging ${identityHashCode(e)} '
'${e.target}, ${e.currentTarget}, ${e.detail}, ${dragInfo}');
_log.finest('e.target == e.currentTarget => ${identical(e.target, e.currentTarget)}');
final HtmlElement avatar = dragInfo['avatar'];
final rect = getBoundingClientRect();
avatar.style.setProperty('width', '${rect.width}px');
avatar.style.setProperty('height', '${rect.height}px');
final dragContainer = $['drag-container'];
final rowContainer = $['row-container'];
rowContainer.style.setProperty('width', '${rect.width}px');
rowContainer.style.setProperty('height', '${rect.height}px');
dragContainer.style.setProperty('width', '${rect.width}px');
dragContainer.style.setProperty('height', '${rect.height}px');
avatar.append(dragContainer.clone(true));
dragContainer.style.display = 'none';
dragInfo['drag'] = drag;
dragInfo['drop'] = drop;
}
drag(JsObject dragInfo) {
print('drag');
final HtmlElement avatar = dragInfo['avatar'];
print(avatar);
}
drop(JsObject dragInfo) {
print('drop');
final HtmlElement avatar = dragInfo['avatar'];
print(avatar);
}
}
@CustomTag('drag-container')
class DragContainer extends PolymerElement with Observable {
bool multi;
DragContainer.created() : super.created() {
_log.finer('DragContainer.created');
print('DragContainer.created');
}
}
-
<core-list-dart height="100" data="{{data}}">
<template>
<draggable-list-item>
<test-row></test-row>
</draggable-list-item>
</template>
</core-list-dart>
答案 0 :(得分:1)
到目前为止,我试图将<core-list-dart>
包裹起来(没有拖放)。
import 'package:polymer/polymer.dart';
import 'package:core_elements/core_list_dart.dart';
@CustomTag('reorderable-list')
class ReorderableList extends PolymerElement {
/// Constructor used to create instance of ReorderableList.
ReorderableList.created() : super.created();
@PublishedProperty(reflect: true)
List<String> data;
attached() {
super.attached();
var template = querySelector('template');
var coreList = (shadowRoot.querySelector('core-list-dart') as CoreList);
coreList.append(template);
}
}
<link rel="import" href="../../packages/polymer/polymer.html">
<link rel="import" href="../../packages/core_elements/core_list_dart.html">
<polymer-element name="reorderable-list">
<template>
<core-list-dart data="{{data}}"></core-list-dart>
<content></content>
</template>
<script type="application/dart" src="reorderable_list.dart"></script>
</polymer-element>
用法(与<core-list-dart>
基本相同)
<link rel="import" href="../../packages/polymer/polymer.html">
<link rel="import" href="../../packages/core_elements/core_list_dart.html">
<link rel="import" href="drag_container.html">
<link rel="import" href="draggable_member.html">
<link rel="import" href="test_element.html">
<link rel="import" href="reorderable_list.html">
<polymer-element name="app-element">
<template>
reorderable-list
<reorderable-list data="{{strings}}">
<template id="app-element-reorderable">
<drag-container>
<draggable-member id="member" draggable="true">
<test-element>{{name}}</test-element>
</draggable-member>
</drag-container>
</template>
</reorderable-list>
</template>
<script type="application/dart" src="app_element.dart"></script>
</polymer-element>
import 'package:polymer/polymer.dart';
class Item {
String name;
Item(this.name);
bool selected = false;
String toString() => name;
}
@CustomTag('app-element')
class AppElement extends PolymerElement {
@observable
List strings = toObservable([new Item('Anton'), new Item('Berta'), new Item('Caesar'), new Item('Dora')]);
AppElement.created() : super.created();
}
我认为当<reorderable-list>
实现drag-n-drop事件处理程序时它应该可以工作。
答案 1 :(得分:0)
我已将所有这些代码添加到https://bitbucket.org/andersmholmgren/ah_polymer_stuff。每个人都可以自由地利用这一点。
我现在非常接近。它的工作原理是我可以移动行。
最后一个障碍是我在拖动过程中丢失了头像中的部分行内容。我很确定它来自我的最后一招。
该元素现在定义为
<polymer-element name="draggable-list-item" on-drag-start="{{startDrag}}">
<template>
<core-style ref="draggable-list-item"></core-style>
<core-drag-drop></core-drag-drop>
<div id="row-container">
<div id="drag-container">
<content></content>
</div>
</div>
</template>
<script type="application/dart" src="draggable_list_item.dart"></script>
</polymer-element>
你就像
一样使用它<core-list-dart height="100" data="{{data}}">
<template>
<draggable-list-item>
<test-row data="{{self}}"></test-row>
</draggable-list-item>
</template>
</core-list-dart>
test-row看起来像
<polymer-element name="test-row" unresolved>
<template>
<h1>hello I'm a row {{data}}</h1>
</template>
</polymer-element>
因此测试行(<test-row data="{{self}}"></test-row>
)最终会成为
<div id="row-container">
<div id="drag-container">
<content></content>
</div>
</div>
正如我之前提到的,ContentElement以神秘的方式表现。为了使其正确呈现,我做了以下
final dragContainer = $['drag-container'];
final ContentElement content = dragContainer.querySelector('content');
print(content.getDistributedNodes());
final dragDiv = new Element.tag('div');
final clonedNodes = content.getDistributedNodes().map((n) =>
n.clone(true));
clonedNodes.forEach((n) {
dragDiv.append(n);
});
dragDiv.style.width = '${rect.width}px';
dragDiv.style.height = '${rect.height}px';
dragDiv.style.border = "solid blue 1px";
avatar.append(dragDiv);
dragContainer.style.display = 'none';
我必须获取并克隆内容的分布式节点。这种方法很好,除了我怀疑这也是为什么我在拖拽时丢失部分行的原因。
通常行呈现为
hello I'm a row data item null with value 2
data item null with value 2
部分来自I&#39; m使用的数据类的toString。
拖动该部分消失,显示的全部是
hello I'm a row
该部分消失的某个地方,我不确定如何解决它
可悲的是,这只适用于dartium。在Chrome中,当你拖动头像似乎只是保持左上角而且永远不会移动。我怀疑这可能只是dart中core_drag_drop中的一个重要部分。