从数组中删除项目时重新呈现列表的问题 javascript
Issue on re-render list when removing an item from an array javascript
我正在尝试创建一个用户可以删除和编辑的文本列表。但是我在尝试实现它时遇到了问题,这是我目前的开发。
为了创建列表,我通过使用此函数映射对象来渲染元素
function textContainer(e, color) {
var textForm = `
<form onsubmit="return false" class="form-inline my-2 text-form row" style="display:flex; justify-content:space-around;">
<input class="col-9 form-control mr-sm-2" type="text" id="newText"
placeholder="Name, Number etc">
<button class="col-2 btn btn-outline-primary my-2 my-sm-0" type="button"
onclick="addText(newText.value)">Add Text</button>
</form>
`;
var textLayer = '';
var id = 0;
var iconColor = 'black';
if (color != null) {
iconColor = color
}
canvas._objects.map(object => {
if (object.text != undefined) {
console.log(object.fill)
id += 1;
textLayer = `
<ul class="listTexts" style="padding :0;">
<li id="text-`+ id + `" class="buttonLists">
<span>`+ id + `. ` + object.text + `</span>
<div>
<i class="fas fa-trash-alt" style="margin:0px 5px;" onclick="removeTextById(`+ id + `)"></i>
</div>
</li>
</ul>
`;
}
});
if (canvas._objects.length == 1) {
$('.textContainer').append(textForm).html();
} else if (e == 'removed') {
$('.textContainer').append(textForm + textLayer).html();
} else if (e == 'changed') {
$('.listTexts').empty();
$('.listTexts').append(textLayer).html();
} else {
$('.textContainer').append(textLayer).html();
}
}
并像这样根据他们的 id 删除项目
function removeTextById(id) {
var array = canvas._objects.filter(function (el) {
return el.text != null
})
canvas.remove(array[id - 1]);
$('.textContainer').empty();
textContainer('removed');
canvas.renderAll();
}
这很好用,如果它只包含列表中的 1 或 2 个项目,我可以删除任何项目。但是当它包含超过 2 个时,例如 3,它会删除 2 li
标签,如果它是 4,它会删除 3 li
标签。我不知道发生了什么,但我的对象是正确的,它只删除了 1 个项目。您可以在此处 https://natestudio.my.id/3d-configurator 在文本选项卡上看到它的实际效果。
有人知道为什么会这样吗?
编辑
canvas
在我的应用程序中是 fabricjs canvas,canvas._objects
return canvas 中的对象列表。我会尝试在一分钟内创建一个简单的重现
编辑 2
这是一个最小的复制https://jsfiddle.net/2758bskq/6/
在执行删除操作时,列表显示在此处:
else if (e == 'removed') {
$('.textContainer').append(textForm + textLayer).html();
在此执行之前,$('.textContainer')
为空。由于 textLayer
仅包含 一个 项目(请参阅上面的循环),删除后最多显示一个项目。
所以一个问题是 textLayer
的收集:它应该收集所有相关项目,而不仅仅是最后一个。所以替换:
textLayer =
与:
textLayer +=
但这会对其他场景(加法,...等)产生不良后果。为避免这种情况,只需重建列表 always.
因此,将 if (canvas._objects.length == 1) {
及其后的整个 if..else
结构替换为:
$('.textContainer').empty().append(textForm + textLayer);
这将解决您提到的问题。
代码段(canvas 尺寸已缩小,因此重点放在列表上):
var canvas = this.__canvas = new fabric.Canvas('canvas', {
backgroundColor: 'white',
centeredScaling: true,
});
function addText(text) {
if (text != '') {
jerseyName = new fabric.IText(text, {
fontSize: 25,
textAlign: 'center',
fontWeight: 'bold',
left: 100,
top: 280,
originX: 'center',
originY: 'center',
selectable: true
});
canvas.add(jerseyName);
canvas.setActiveObject(jerseyName);
textContainer();
$('.text-form').each(function() {
this.reset();
});
}
}
function textContainer() {
var textForm = `
<form onsubmit="return false" class="form-inline my-2 text-form row" style="display:flex; justify-content:space-around;">
<input class="col-9 form-control mr-sm-2" type="text" id="newText"
placeholder="Name, Number etc">
<button class="col-2 btn btn-outline-primary my-2 my-sm-0" type="button"
onclick="addText(newText.value)">Add Text</button>
</form>
`;
var textLayer = '';
var id = 0;
canvas._objects.map(object => {
if (object.text != undefined) {
id += 1;
textLayer += `
<ul class="listTexts" style="padding :0;">
<li id="text-` + id + `" class="buttonLists">
<span>` + id + `. ` + object.text + `</span>
<div>
<button onclick="removeTextById(` + id + `)">Remove</button>
</div>
</li>
</ul>
`;
}
});
$('.textContainer').empty().append(textForm + textLayer);
}
function removeTextById(id) {
var array = canvas._objects.filter(function(el) {
return el.text != null
})
canvas.remove(array[id - 1]);
textContainer();
canvas.renderAll();
}
textContainer();
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="canvas" height="10" width="400"></canvas>
<div class="tab-pane p-3 textContainer" id="tabs-2" role="tabpanel" aria-labelledby="two-tab">
</div>
我正在尝试创建一个用户可以删除和编辑的文本列表。但是我在尝试实现它时遇到了问题,这是我目前的开发。
为了创建列表,我通过使用此函数映射对象来渲染元素
function textContainer(e, color) {
var textForm = `
<form onsubmit="return false" class="form-inline my-2 text-form row" style="display:flex; justify-content:space-around;">
<input class="col-9 form-control mr-sm-2" type="text" id="newText"
placeholder="Name, Number etc">
<button class="col-2 btn btn-outline-primary my-2 my-sm-0" type="button"
onclick="addText(newText.value)">Add Text</button>
</form>
`;
var textLayer = '';
var id = 0;
var iconColor = 'black';
if (color != null) {
iconColor = color
}
canvas._objects.map(object => {
if (object.text != undefined) {
console.log(object.fill)
id += 1;
textLayer = `
<ul class="listTexts" style="padding :0;">
<li id="text-`+ id + `" class="buttonLists">
<span>`+ id + `. ` + object.text + `</span>
<div>
<i class="fas fa-trash-alt" style="margin:0px 5px;" onclick="removeTextById(`+ id + `)"></i>
</div>
</li>
</ul>
`;
}
});
if (canvas._objects.length == 1) {
$('.textContainer').append(textForm).html();
} else if (e == 'removed') {
$('.textContainer').append(textForm + textLayer).html();
} else if (e == 'changed') {
$('.listTexts').empty();
$('.listTexts').append(textLayer).html();
} else {
$('.textContainer').append(textLayer).html();
}
}
并像这样根据他们的 id 删除项目
function removeTextById(id) {
var array = canvas._objects.filter(function (el) {
return el.text != null
})
canvas.remove(array[id - 1]);
$('.textContainer').empty();
textContainer('removed');
canvas.renderAll();
}
这很好用,如果它只包含列表中的 1 或 2 个项目,我可以删除任何项目。但是当它包含超过 2 个时,例如 3,它会删除 2 li
标签,如果它是 4,它会删除 3 li
标签。我不知道发生了什么,但我的对象是正确的,它只删除了 1 个项目。您可以在此处 https://natestudio.my.id/3d-configurator 在文本选项卡上看到它的实际效果。
有人知道为什么会这样吗?
编辑
canvas
在我的应用程序中是 fabricjs canvas,canvas._objects
return canvas 中的对象列表。我会尝试在一分钟内创建一个简单的重现
编辑 2
这是一个最小的复制https://jsfiddle.net/2758bskq/6/
在执行删除操作时,列表显示在此处:
else if (e == 'removed') {
$('.textContainer').append(textForm + textLayer).html();
在此执行之前,$('.textContainer')
为空。由于 textLayer
仅包含 一个 项目(请参阅上面的循环),删除后最多显示一个项目。
所以一个问题是 textLayer
的收集:它应该收集所有相关项目,而不仅仅是最后一个。所以替换:
textLayer =
与:
textLayer +=
但这会对其他场景(加法,...等)产生不良后果。为避免这种情况,只需重建列表 always.
因此,将 if (canvas._objects.length == 1) {
及其后的整个 if..else
结构替换为:
$('.textContainer').empty().append(textForm + textLayer);
这将解决您提到的问题。
代码段(canvas 尺寸已缩小,因此重点放在列表上):
var canvas = this.__canvas = new fabric.Canvas('canvas', {
backgroundColor: 'white',
centeredScaling: true,
});
function addText(text) {
if (text != '') {
jerseyName = new fabric.IText(text, {
fontSize: 25,
textAlign: 'center',
fontWeight: 'bold',
left: 100,
top: 280,
originX: 'center',
originY: 'center',
selectable: true
});
canvas.add(jerseyName);
canvas.setActiveObject(jerseyName);
textContainer();
$('.text-form').each(function() {
this.reset();
});
}
}
function textContainer() {
var textForm = `
<form onsubmit="return false" class="form-inline my-2 text-form row" style="display:flex; justify-content:space-around;">
<input class="col-9 form-control mr-sm-2" type="text" id="newText"
placeholder="Name, Number etc">
<button class="col-2 btn btn-outline-primary my-2 my-sm-0" type="button"
onclick="addText(newText.value)">Add Text</button>
</form>
`;
var textLayer = '';
var id = 0;
canvas._objects.map(object => {
if (object.text != undefined) {
id += 1;
textLayer += `
<ul class="listTexts" style="padding :0;">
<li id="text-` + id + `" class="buttonLists">
<span>` + id + `. ` + object.text + `</span>
<div>
<button onclick="removeTextById(` + id + `)">Remove</button>
</div>
</li>
</ul>
`;
}
});
$('.textContainer').empty().append(textForm + textLayer);
}
function removeTextById(id) {
var array = canvas._objects.filter(function(el) {
return el.text != null
})
canvas.remove(array[id - 1]);
textContainer();
canvas.renderAll();
}
textContainer();
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="canvas" height="10" width="400"></canvas>
<div class="tab-pane p-3 textContainer" id="tabs-2" role="tabpanel" aria-labelledby="two-tab">
</div>