将新创建的元素附加到父窗口时保留.data()值

时间:2012-03-06 14:38:14

标签: javascript jquery json ajax append

我在弹出窗口中运行了一段jQuery代码,用于解析来自AJAX请求的JSON响应。作为其中的一部分,它动态创建一系列<tr>元素 - 其内容包括使用.data()函数分配给它们的数据属性的锚元素 - 来更新父窗口中的表。 / p>

此代码按预期工作。使用正确的内容创建行,然后将其添加到主窗口中的表中。只有一个小问题 - 附加到锚元素的数据消失了。

JSON响应如下所示(相关部分是locationList数组):

{
  "locationList": [{
    "name": "All locations",
    "locid": "-1",
    "countryid": "-1",
    "imtid": "-1"
  }],
  "countries": [
    {
      "value": "-1",
      "text": "All"
    },
    {
      "value": "258",
      "text": "Ireland"
    },
    {
      "value": "246",
      "text": "Sub SA"
    },
    {
      "value": "261",
      "text": "United Kingdom"
    }
  ],
  "locations": [{
    "value": "-1",
    "text": "All"
  }]
}

Javascript看起来像这样:

var $locations = opener.$('#document-content-locations');
$locations.empty();
for(var i = 0; i < data.locationList.length; i++) {
    var location = data.locationList[i];
    var rowClass = (i % 2 == 0) ? "odd" : "even";
    var row = $('<tr/>').addClass(rowClass);
    row.append($('<td/>').text(location.name));
    var link = $('<a/>').attr('href', '#').data({locid: location.locid, countryid: location.countryid, imtid: location.imtid}).text('remove').addClass('removelocation');
    console.log(link.data());
    row.append($('<td/>').append(link));
    console.log(row.find('a').data());
    $locations.append(row);
    console.log($locations.find('a').data());
}

console.log调用在那里通过各个阶段监视元素data。控制台输出:

Object { locid="-1", countryid="-1", imtid="-1"}
Object { locid="-1", countryid="-1", imtid="-1"}
Object {}

认为正在发生的事情是调用.append(),而不是简单地将元素附加到主窗口的表中,克隆元素(减去数据和事件信息)然后将其添加到主窗口中的表。我尝试显式克隆元素(传递true以保存数据和事件),然后附加该元素,但问题仍然存在。

我可以使用HTML中的HTML5 data-*属性来解决此问题,而不是使用.data()函数。现在这很好,因为只有少数,但它不那么容易扩展。

所以,我有几个问题:

  1. 我的想法/假设可能是正确的吗?正在打电话 .append()使用弹出窗口中新创建的元素添加到 父窗口中的元素可能克隆元素(即使似乎没有理由这样做)?
  2. 有没有办法 - 除了进入和修改jQuery源代码 - 告诉你 .append()(以及类似的函数)来保存数据和事件 它作为执行的一部分创建的任何克隆的信息(我不认为默认情况下会这样做)?
  3. 我在上面的代码中做了哪些内容错误导致问题?

2 个答案:

答案 0 :(得分:2)

花了我一段时间(大约一年 - 我忘了回来,当我第一次发现它时回答这个问题)才意识到这里发生的事情并导致我遇到的问题。当我问这个问题时,我对DOM节点的数据存储方式并没有任何了解,但是当我调用.data()来设置和获取时,我对内部发生的事情有了更好的(如果不是完全完整的)概念。值。

对于DOM节点,jQuery有一个全局缓存,用于存储所有数据。然后为每个节点分配一个唯一的ID,该ID充当密钥,以便稍后从缓存中检索该特定节点的数据。

这一切都相对简单,那为什么它不能在浏览器窗口之间工作呢?答案是(现在)非常明显:每个单独的窗口都有自己的全局缓存,在子窗口(弹出窗口)窗口中设置数据时生成的唯一ID与父窗口的全局缓存中的条目不匹配(如果它甚至都被转移了。)

答案 1 :(得分:1)

看起来.append()有时会移动,有时会克隆。

http://welcome.totheinter.net/2009/03/19/the-undocumented-life-of-jquerys-append/

我使用.append()看过同样的事情。在我的例子中,我以编程方式创建锚点并将事件处理程序绑定到它们。然后我将.adpend()锚点对象放在DOM的其他地方,它们就会丢失它们的事件处理程序。