如果试图从可排序组中仅移动一张卡片,则会拖拽两个可排序项目
Two sortable items dragged if trying to move just one card from the sortable group
我已经在 Polymer2.0 元素中实现了 sortablejs。我可以从组中拖放项目。我现在面临的问题是随机的,不确定为什么以及如何,但是 2 张卡片或项目在组列表中移动。这是屏幕截图。
todos 是一个对象,它包含一组列表,这些列表具有项目数组。
列表
https://www.dropbox.com/s/9wp6vv668p3ckr2/Screenshot%202019-04-30%2007.18.16.png?dl=0
放下时的结束状态(你看到 2 张卡片移到了我不想要的新列。我只想要一张卡片移动)
https://www.dropbox.com/s/int4uyyl3945tjv/Screenshot%202019-04-30%2007.18.50.png?dl=0
代码:聚合物元素 html
<div class="board__sprint">
<template is="dom-repeat" items="{{todos}}" as="row" restamp>
<div class="list">
<div class="list-content">
<div style="float: left; width: 100%; text-align: center;">
<div style="float: left; width: 80%; text-align: left; padding-top: 10px;">
<h7 style="color: black; font-size: 20px; font-weight: 800; padding-left: 10px;margin-top: 5px;">
[[row.tasks.length]]
</h7>
<h7 style="color: black; font-size: 12px; font-weight: 200; padding: 2px; margin-top: 5px;">
[[row.title]]
</h7>
</div>
<div style="float: left; width: 20%; text-align: center;">
<paper-icon-button icon="icons:delete-sweep" style="color: grey;" id="deleteNote" row="[[row]]"
on-tap="_removeColumnTriggerDialog"></paper-icon-button>
</div>
</div>
<div style="display: table;">
<div style="width: 90%; height: 3px; background: #0c66b5;">
<h7> </h7>
</div>
<div id="myid[[row.id]]" class="list-group" style="min-height: 120px;">
<template is="dom-repeat" items="{{row.tasks}}" as="todo" restamp>
<!-- <div class$="{{determineDragable(todo)}}"> -->
<div class="item">
<div class="ticket" data-index$="{{todo.id}}">
<paper-card style="float:center; width: 100%;" class="singleColor" data-index$="{{todo}}"
data-index$="{{row}}">
<div style="float:left; width: 15%" style$="{{getRandomInt(0, 20)}}">
<h7> </h7>
</div>
<div style="width: 100%">
<div style="float: left; width: 15%; vertical-align:center">
<px-icon icon="px-vis:pin"></px-icon>
</div>
<div style="float: left; width: 70%">
<h7 class="banksTitle" style="color: black; font-size: 12px; text-align:left;">
<b>[{{index}}]</b> [[todo.actTitle]]
</h7>
<h7 class="banksTitle" style="color: grey; font-size: 12px; text-align:left;">
[[todo.actDesc]]
</h7>
</div>
<template is="dom-if" if="{{checkDummy(todo)}}">
<div style="float: left; width: 15%;">
<paper-icon-button icon="icons:close" style="color: grey;" id$="bt_readmore"
todo="[[todo]]" row="[[row]]" on-tap="_moveDel"></paper-icon-button>
</div>
</template>
<template is="dom-if" if="{{checkDummyNot(todo)}}">
<div style="float: left; width: 15%;">
<paper-icon-button icon="image:crop-square" style="color: grey;" id$="bt_readmore"
todo="[[todo]]" row="[[row]]" on-tap=""></paper-icon-button>
</div>
</template>
</div>
<div>
<h5> </h5>
</div>
<div style="width: 100%;display: table;">
<div style="float: left; width: 15%;">
</div>
<div style="float: left; width: 70%; text-align: center;">
<template is="dom-if" if="{{checkDummy(todo)}}">
<paper-icon-button icon="av:playlist-add-check" style="color: green;"
id$="bt_readmore" todo="[[todo]]" row="[[row]]" on-tap=""></paper-icon-button>
</template>
<template is="dom-if" if="{{checkDummy(todo)}}">
<paper-icon-button icon="editor:attach-file" style="color: maroon;" id$="bt_readmore"
todo="[[todo]]" row="[[row]]" on-tap=""></paper-icon-button>
</template>
<template is="dom-if" if="{{checkDummy(todo)}}">
<paper-icon-button icon="editor:border-color" style="color: grey;" id$="bt_readmore"
todo="[[todo]]" row="[[row]]" on-tap=""></paper-icon-button>
</template>
</div>
<div style="float: right; width: 15%;">
</div>
</div>
</paper-card>
</div>
</div>
</template>
</div>
</div>
<div>
<h5> </h5>
</div>
<div class="addTicket">
<paper-button raised class="blue" on-tap="_addTicketDialog" row={{row}}>Add Ticket</paper-button>
</div>
</div>
</div>
</template>
</div>
以及sortablejs的onAdd事件特有的JS脚本
_todosChanged() {
setTimeout(() => {
console.log('this.todos.length = ' + this.todos.length);
var self = this;
if (this.todos !== null || this.todos !== undefined) {
var lowestOrder = 0;
var highestOrder = 0;
var options = {
group: 'shared',
animation: 200,
sort: false,
draggable: ".item",
onAdd: function (evt) {
console.log('---FROM----');
console.log(evt.from.id);
console.log('---TO----');
console.log(evt.to.id);
console.log('---ITEM----');
console.log(evt.item.innerText);
var foundFrom = false;
var fromId = evt.from.id.substr('myid'.length);
var fromCol;
var foundTo = false;
var toId = evt.to.id.substr('myid'.length);
var toCol;
console.log('fromId =' + fromId + ' toId =' + toId);
self.todos.forEach(child => { //todos = 1, 3, 4 & row = 3
if (!foundTo) {
if (child.id === toId) {
foundTo = true;
toCol = child;
}
}
if (!foundFrom) {
if (child.id === fromId) {
foundFrom = true;
fromCol = child;
}
}
});
console.log('toCol = ' + JSON.stringify(toCol));
console.log('fromCol = ' + JSON.stringify(fromCol));
//find item in from col
var str = evt.item.innerText;
var itemKey = str.substr(0, str.indexOf(':'));
itemKey = itemKey.substr(itemKey.indexOf('KEY-')).substr('KEY-'.length);
console.log('itemKey = ' + itemKey);
var arrItemToRemove = fromCol.tasks;
console.log('arrItemToRemove = ' + JSON.stringify(arrItemToRemove));
var indexItem = -1;
for (var i = 0; i < arrItemToRemove.length; i++)
if (arrItemToRemove[i].id === itemKey) indexItem = i;
console.log('indexItem = ' + indexItem);
if (indexItem < 0 || indexItem > arrItemToRemove.length) {
document.getElementById('toastError').show('No item found');
} else {
// console.log('indexItem=' + indexItem);
var newItemToPush = arrItemToRemove[indexItem];
console.log('newItemToPush=' + JSON.stringify(newItemToPush));
//now add the item to the right
var arr = toCol.tasks;
if (arr === null || arr === undefined) arr = [];
arr.push({
'actTitle': newItemToPush.actTitle,
'actDesc': newItemToPush.actDesc,
'actDt': newItemToPush.actDt,
'parent': toCol.order,
'id': newItemToPush.id
});
console.log('arr=' + JSON.stringify(arr));
self.$.query.ref.child(toCol.$key).child('tasks').set(arr);
var nwArr = arrItemToRemove.splice(indexItem, 1);
document.getElementById('toastShort').show('Data moved: ' + newItemToPush.actTitle);
self.$.query.ref.child(fromCol.$key).child('tasks').set(arrItemToRemove);
}
},
};
this.todos.forEach(child => {
if (lowestOrder > child.order) lowestOrder = child.order;
if (highestOrder < child.order) highestOrder = child.order;
// console.log(child.id);
var selector = this.shadowRoot.querySelector('#myid' + child.id);
Sortable.create(selector, options);
});
console.log('lowestOrder=' + lowestOrder + ' highestOrder=' + highestOrder);
this.set('order', highestOrder);
}
});
}
好的...这就是我解决问题的方法
firebase 查询是异步的,所以我使用观察者函数来更新 dom-模板中使用的虚拟变量。我使用异步来做到这一点。
真正的问题是当您从 sortablejs 用于呈现项目的列表中删除元素时。通过使用作为 firebase 对象副本的虚拟变量,我能够避免这个问题。
我在用户离开页面时离线同步对象。现在可以正常使用了。
我已经在 Polymer2.0 元素中实现了 sortablejs。我可以从组中拖放项目。我现在面临的问题是随机的,不确定为什么以及如何,但是 2 张卡片或项目在组列表中移动。这是屏幕截图。
todos 是一个对象,它包含一组列表,这些列表具有项目数组。
列表 https://www.dropbox.com/s/9wp6vv668p3ckr2/Screenshot%202019-04-30%2007.18.16.png?dl=0
放下时的结束状态(你看到 2 张卡片移到了我不想要的新列。我只想要一张卡片移动) https://www.dropbox.com/s/int4uyyl3945tjv/Screenshot%202019-04-30%2007.18.50.png?dl=0
代码:聚合物元素 html
<div class="board__sprint">
<template is="dom-repeat" items="{{todos}}" as="row" restamp>
<div class="list">
<div class="list-content">
<div style="float: left; width: 100%; text-align: center;">
<div style="float: left; width: 80%; text-align: left; padding-top: 10px;">
<h7 style="color: black; font-size: 20px; font-weight: 800; padding-left: 10px;margin-top: 5px;">
[[row.tasks.length]]
</h7>
<h7 style="color: black; font-size: 12px; font-weight: 200; padding: 2px; margin-top: 5px;">
[[row.title]]
</h7>
</div>
<div style="float: left; width: 20%; text-align: center;">
<paper-icon-button icon="icons:delete-sweep" style="color: grey;" id="deleteNote" row="[[row]]"
on-tap="_removeColumnTriggerDialog"></paper-icon-button>
</div>
</div>
<div style="display: table;">
<div style="width: 90%; height: 3px; background: #0c66b5;">
<h7> </h7>
</div>
<div id="myid[[row.id]]" class="list-group" style="min-height: 120px;">
<template is="dom-repeat" items="{{row.tasks}}" as="todo" restamp>
<!-- <div class$="{{determineDragable(todo)}}"> -->
<div class="item">
<div class="ticket" data-index$="{{todo.id}}">
<paper-card style="float:center; width: 100%;" class="singleColor" data-index$="{{todo}}"
data-index$="{{row}}">
<div style="float:left; width: 15%" style$="{{getRandomInt(0, 20)}}">
<h7> </h7>
</div>
<div style="width: 100%">
<div style="float: left; width: 15%; vertical-align:center">
<px-icon icon="px-vis:pin"></px-icon>
</div>
<div style="float: left; width: 70%">
<h7 class="banksTitle" style="color: black; font-size: 12px; text-align:left;">
<b>[{{index}}]</b> [[todo.actTitle]]
</h7>
<h7 class="banksTitle" style="color: grey; font-size: 12px; text-align:left;">
[[todo.actDesc]]
</h7>
</div>
<template is="dom-if" if="{{checkDummy(todo)}}">
<div style="float: left; width: 15%;">
<paper-icon-button icon="icons:close" style="color: grey;" id$="bt_readmore"
todo="[[todo]]" row="[[row]]" on-tap="_moveDel"></paper-icon-button>
</div>
</template>
<template is="dom-if" if="{{checkDummyNot(todo)}}">
<div style="float: left; width: 15%;">
<paper-icon-button icon="image:crop-square" style="color: grey;" id$="bt_readmore"
todo="[[todo]]" row="[[row]]" on-tap=""></paper-icon-button>
</div>
</template>
</div>
<div>
<h5> </h5>
</div>
<div style="width: 100%;display: table;">
<div style="float: left; width: 15%;">
</div>
<div style="float: left; width: 70%; text-align: center;">
<template is="dom-if" if="{{checkDummy(todo)}}">
<paper-icon-button icon="av:playlist-add-check" style="color: green;"
id$="bt_readmore" todo="[[todo]]" row="[[row]]" on-tap=""></paper-icon-button>
</template>
<template is="dom-if" if="{{checkDummy(todo)}}">
<paper-icon-button icon="editor:attach-file" style="color: maroon;" id$="bt_readmore"
todo="[[todo]]" row="[[row]]" on-tap=""></paper-icon-button>
</template>
<template is="dom-if" if="{{checkDummy(todo)}}">
<paper-icon-button icon="editor:border-color" style="color: grey;" id$="bt_readmore"
todo="[[todo]]" row="[[row]]" on-tap=""></paper-icon-button>
</template>
</div>
<div style="float: right; width: 15%;">
</div>
</div>
</paper-card>
</div>
</div>
</template>
</div>
</div>
<div>
<h5> </h5>
</div>
<div class="addTicket">
<paper-button raised class="blue" on-tap="_addTicketDialog" row={{row}}>Add Ticket</paper-button>
</div>
</div>
</div>
</template>
</div>
以及sortablejs的onAdd事件特有的JS脚本
_todosChanged() {
setTimeout(() => {
console.log('this.todos.length = ' + this.todos.length);
var self = this;
if (this.todos !== null || this.todos !== undefined) {
var lowestOrder = 0;
var highestOrder = 0;
var options = {
group: 'shared',
animation: 200,
sort: false,
draggable: ".item",
onAdd: function (evt) {
console.log('---FROM----');
console.log(evt.from.id);
console.log('---TO----');
console.log(evt.to.id);
console.log('---ITEM----');
console.log(evt.item.innerText);
var foundFrom = false;
var fromId = evt.from.id.substr('myid'.length);
var fromCol;
var foundTo = false;
var toId = evt.to.id.substr('myid'.length);
var toCol;
console.log('fromId =' + fromId + ' toId =' + toId);
self.todos.forEach(child => { //todos = 1, 3, 4 & row = 3
if (!foundTo) {
if (child.id === toId) {
foundTo = true;
toCol = child;
}
}
if (!foundFrom) {
if (child.id === fromId) {
foundFrom = true;
fromCol = child;
}
}
});
console.log('toCol = ' + JSON.stringify(toCol));
console.log('fromCol = ' + JSON.stringify(fromCol));
//find item in from col
var str = evt.item.innerText;
var itemKey = str.substr(0, str.indexOf(':'));
itemKey = itemKey.substr(itemKey.indexOf('KEY-')).substr('KEY-'.length);
console.log('itemKey = ' + itemKey);
var arrItemToRemove = fromCol.tasks;
console.log('arrItemToRemove = ' + JSON.stringify(arrItemToRemove));
var indexItem = -1;
for (var i = 0; i < arrItemToRemove.length; i++)
if (arrItemToRemove[i].id === itemKey) indexItem = i;
console.log('indexItem = ' + indexItem);
if (indexItem < 0 || indexItem > arrItemToRemove.length) {
document.getElementById('toastError').show('No item found');
} else {
// console.log('indexItem=' + indexItem);
var newItemToPush = arrItemToRemove[indexItem];
console.log('newItemToPush=' + JSON.stringify(newItemToPush));
//now add the item to the right
var arr = toCol.tasks;
if (arr === null || arr === undefined) arr = [];
arr.push({
'actTitle': newItemToPush.actTitle,
'actDesc': newItemToPush.actDesc,
'actDt': newItemToPush.actDt,
'parent': toCol.order,
'id': newItemToPush.id
});
console.log('arr=' + JSON.stringify(arr));
self.$.query.ref.child(toCol.$key).child('tasks').set(arr);
var nwArr = arrItemToRemove.splice(indexItem, 1);
document.getElementById('toastShort').show('Data moved: ' + newItemToPush.actTitle);
self.$.query.ref.child(fromCol.$key).child('tasks').set(arrItemToRemove);
}
},
};
this.todos.forEach(child => {
if (lowestOrder > child.order) lowestOrder = child.order;
if (highestOrder < child.order) highestOrder = child.order;
// console.log(child.id);
var selector = this.shadowRoot.querySelector('#myid' + child.id);
Sortable.create(selector, options);
});
console.log('lowestOrder=' + lowestOrder + ' highestOrder=' + highestOrder);
this.set('order', highestOrder);
}
});
}
好的...这就是我解决问题的方法
firebase 查询是异步的,所以我使用观察者函数来更新 dom-模板中使用的虚拟变量。我使用异步来做到这一点。
真正的问题是当您从 sortablejs 用于呈现项目的列表中删除元素时。通过使用作为 firebase 对象副本的虚拟变量,我能够避免这个问题。
我在用户离开页面时离线同步对象。现在可以正常使用了。