如何将javascript数组绑定到HTML,同时允许从数组中添加和删除

How do I bind a javascript array to HTML while allowing adding and deleting from the array?

本文关键字:数组 添加 删除 javascript 绑定 HTML      更新时间:2023-09-26

所以问题是,当我从现有数组中添加和删除时,如何保持HTML元素同步。

如果我有一个javascript对象的数组元素1是:
{
  "firstName": "John",
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021-3100"
  },
  "phoneNumbers": [
    {
      "type": "home",
      "number": "212 555-1234"
    },
    {
      "type": "office",
      "number": "646 555-4567"
    }
    ....
  ]
  .... ETC ETC COMPLICATED ....
}

那么我的初始html可以通过使用数组索引为每个初始大小的对象生成3个元素[{},{},{}]:

<div id="arrayPos-0">
    <div>John</div>
    <input>PROCESS<input>
    <input>DELETE<input>
</div>
<div id="arrayPos-1">
    <div>Sam</div>
    <input>PROCESS<input>
    <input>DELETE<input>
</div>
<div id="arrayPos-2">
    <div>Timmy</div>
    <input>PROCESS<input>
    <input>DELETE<input>
</div>

如果我添加到Javascript数组,我希望增加它并成为[{},{},{},{}]:

<div id="arrayPos-0">
    ...
</div>
<div id="arrayPos-1">
    ...
</div>
<div id="arrayPos-2">
    ...
</div>
<div id="arrayPos-3">
    <div>Simone</div>
    <input>PROCESS<input>
    <input>DELETE<input>
</div>

然而,一旦我从javascript数组中删除说索引2 (arrayPos-2),我得到以下HTML:

<div id="arrayPos-0">
    ...
</div>
<div id="arrayPos-1">
    ...
</div>
<div id="arrayPos-3">
    ...
</div>

这一切都搞砸了,我无法匹配 "arrayPos-3"现在索引2。另外,当我添加一个新的javascript对象index 3:

<div id="arrayPos-0">
    ...
</div>
<div id="arrayPos-1">
    ...
</div>
<div id="arrayPos-3">
    ...
</div>
<div id="arrayPos-3">
    ...
</div>

我无法使用AngularJS,因此由于旧浏览器需要支持,ng-repeat无法使用。如果使用观察者将javascript对象直接绑定到html标记,那么将非常简单。

我只能使用jQuery和常规javascript。但这个问题肯定可以用更简单的方式解决吗?我是否需要使用id进行绑定?我是否需要为ID自动生成guid,并使用字典来匹配ID与Javascript对象索引(我希望不是)?

最简单的方法是有一个生成器函数,它将在任何更改(添加/删除/编辑)后重新生成HTML。

这样你就不会对id有任何困惑,并且总是在DOM中表示当前的JS对象。这是相当"Angularish"的方式——从JS数据构建DOM,而不关心DOM中有什么。

这里有一个超级简单的例子来说明我的意思:

var data = [
  {name: 'John'},
  {name: 'Shomz'},
  {name: 'Jimmy'}
]
var c = document.getElementById('c');
function build() {
  var output = "";
  for(var i = 0; i < data.length; i++) {
    output += '<div id="arrayPos-' + i + '"><button onclick="del(' + i + ')">Del</button><button onclick="edit(' + i + ')">Edit</button>' + data[i].name + '</div>';
  }
  c.innerHTML = output;
}
function del(id) {
  data.splice(id ,1);
  document.getElementById('arrayPos-' + id).className = 'del';
  setTimeout(build, 200);
}
function add() {
  data.push({name: prompt('Enter name')}); 
  build();
}
function edit(id) {
  data[id].name = prompt('Enter name', data[id].name); 
  build();
}
build();
#arrayPos-0 {color: green}
button {margin: 4px}
#c div {opacity: 1; transition: all 0.2s linear}
#c div:hover {background: #eee}
#c div.del {opacity: 0}
<div id="c"></div>
<br>
<button onclick="add()">Add</button>

您可以使用JQuery的.attr()方法在遍历数组中的对象时动态设置id属性—如果您想采用这种方法的话。您还可以使用JQuery的.html()动态设置内部html,以设置div的内容。如果您回顾了使用JQuery遍历DOM,将有助于使用后一种方法。希望能有所帮助-

如果你想保持这种方式并保持它们的顺序,那么你可以创建一个函数:1.删除当前div2. 用对应的新id

以新顺序重新生成div

让这个函数每次你从数组中添加或删除一些东西时触发。这是相对简单的,不会花费javascript那么长的时间。

或:

创建一个for循环,循环遍历数组并确定名称为"x"的对象在数组中的位置(循环次数),并将其分配给div。

可以使用jQuery .index()方法获取元素相对于同级元素的索引。这样,您就可以将它与数组中的索引进行匹配。不需要为元素添加id。

假设您已经有了一个索引,并且想要访问dom元素。你可以这样做:

$('.class-name').get(index).remove();

或者,如果你正在响应某个事件,而你不确定它对应于数组中的哪个元素,你可以这样做:

$('.class-name').click(function(e){
    var index = $('.class-name').index(e.target);
});

在我的例子中,我使用点击事件,但它可以是任何其他方式

在这种情况下,如果您可以修改现有的js object,我建议对html elementjs object使用id。

也许你可以做点什么:

var id = Math.random().toString(16).slice(-6); // for random id, aplha-numeric
html:

<div id="23xc45">
    ...
</div>
<div id="cd567u">
    ...
</div>

js对象:

[{
  "id" : "23xc45",
  "firstName": "John",
  ...
},{
  "id" : "cd567u",
  "firstName": "Sam",
  ...
}]