具有就地区域更新的 Tapestry 网格因网格数据中的单引号而失败

Tapestry Grid with inPlace zone update fails with single quote in data for grid

我在组件中有以下网格。

<t:grid t:id="resultsGrid" id="resultsGrid" inPlace="true" source="results" row="result" rowIndex="rowIndex" rowsPerPage="50" pagerPosition="top" model="model">

InPlace=true 在区域内呈现网格,然后每个新页面请求仅更新该区域。但在以下情况下,区域更新不会发生。

假设第 3 页,网格数据(行)包含单引号。第 3 页呈现正常,但之后如果您单击任何其他页码,则该区域不会更新。浏览器确实从服务器接收到新页面的数据,但区域更新没有发生。

只有当 data/text 的网格包含单引号时才会发生这种情况,例如当某行网格中有 "Adam's" 时。如果网格数据不包含单引号,区域更新正常。

在更多调试中,我发现问题始于 tapestry.js 文件的以下功能。

在区域更新过程中,以下函数调用purgeChildren(element)函数。

/**
     * Updates the zone's content, and invokes either the update function (to
     * highlight the change) or the show function (to reveal a hidden element).
     * Lastly, fires the Tapestry.ZONE_UPDATED_EVENT to let listeners know that
     * the zone was updated.
     * 
     * @param content
     */
    show : function(content) {

        Tapestry.purgeChildren(this.updateElement);

        this.updateElement.update(content);

        var func = this.element.visible() ? this.updateFunc : this.showFunc;

        func.call(this, this.element, this.endcolor);

        this.element.fire(Tapestry.ZONE_UPDATED_EVENT);
    },

下面是调用purge(element)函数的purgeChildren(element)函数。

/**
     * Invokes purge() on all the children of the element.
     */
    purgeChildren : function(element) {

        var children = element.childNodes;

        if (children) {
            var l = children.length, i, child;

            for (i = 0; i < l; i++) {
                var child = children[i];

                /* Just purge element nodes, not text, etc. */
                if (child.nodeType == 1)
                    Tapestry.purge(children[i]);
            }
        }
    }

最后,下面是 purge(element) 函数,它是区域更新过程中断的地方。在这个函数中'Unexpected identifier'当网格数据包含单引号时抛出异常

//this is where the problem is.
/**
     * Purges the element of any event handlers (necessary in IE to ensure that
     * memory leaks do not occur, and harmless in other browsers). The element
     * is purged, then any children of the element are purged.
     */
    purge : function(element) {

        // removes all functions/handlers attached to this element
        /* Adapted from http://javascript.crockford.com/memory/leak.html */
        var attrs = element.attributes;
        if (attrs) {
            var i, name;
            for (i = attrs.length - 1; i >= 0; i--) {
                if (attrs[i]) {
                    name = attrs[i].name;
                    /* Looking for onclick, etc. */
                    if (typeof element[name] == 'function') {
                        element[name] = null;
                    }
                }
            }
        }

        /* Get rid of any Prototype event handlers as well. */
        Event.stopObserving(element);

        Tapestry.purgeChildren(element);
    },

如评论中所述 purge(element) 函数删除元素的所有处理函数,并且在 IE 中可能是内存泄漏所必需的。

我可以通过按以下方式更改 purge(element) 功能来解决问题。注释掉删除元素处理程序的代码。进行此更改后,即使数据包含单引号,区域也会正常更新。

purge : function(element) {

    // removes all functions/handlers attached to this element
    /* Adapted from http://javascript.crockford.com/memory/leak.html */
//  var attrs = element.attributes;
//  if (attrs) {
//      var i, name;
//      for (i = attrs.length - 1; i >= 0; i--) {
//          if (attrs[i]) {
//              name = attrs[i].name;
//              // Looking for onclick, etc
//              if (typeof element[name] == 'function') {
//                  element[name] = null;
//              }
//          }
//      }
//  }

    /* Get rid of any Prototype event handlers as well. */
    Event.stopObserving(element);

//  Tapestry.purgeChildren(element);
},

但这不是一个好的修复。我有以下问题,任何帮助都会很好。

1: 为什么清除函数中的代码在删除传递元素的处理程序时会在数据中用单引号中断?

2:数据从扩展 GridDataSource 接口的源 class 馈送到网格。因此,网格数据是由挂毯从该来源生成的class,因此特殊字符的处理也应该由挂毯完成。如果我在网格的数据容器 class 中添加 toString() 方法会有帮助吗?

3: 是否有任何其他方法可以实现清除(元素) 函数,使其不会与数据中的单引号分开?

4: 我正在使用 tapestry 5.2.4 版本 ,如果我升级到最新版本可以解决这个问题吗?

5: 改变 purge(element) 函数以避免异常的潜在问题是什么? unsafe/safe 变化如何?

关于您的问题 4,看起来它在 Tapestry 5.3.7 中工作得很好:

http://jumpstart.doublenegative.com.au/jumpstart/examples/ajax/filteredgrid

和 Tapestry 5.4-beta-26:

http://jumpstart.doublenegative.com.au/jumpstart7/examples/ajax/filteredgrid

如果在您阅读本文时数据中没有单引号,请使用许多 "CRUD" 示例之一将单引号放入人名中。

忘记post回答。

问题是每个网格行的内容都包含一个图像。对于该图像,onClick 处理程序传递了从服务器返回的页面名称,没有转义特殊字符。因此在更新区域时出现问题。

在将页面发送到浏览器之前转义页面名称修复了该问题。