jQuery范围问题

时间:2009-08-12 14:14:15

标签: javascript jquery xml scope

我正在尝试创建一种通用的xml解析器,如下所示:

第1部分:

创建了一个带过滤器的对象:

var product = {

  holder : {
    id: '',
    title: '',
    text : '',
    price: ''
  },

  filter : {
    id: '',
    test: function( elementHolder ) {
      if( elementHolder.id == product.filter.id ) {
        return true;
      }
      return false;
    }
  }
}

第2部分:

xml解析器:

/*
 * Generic XML parser
 * Parses the url into elementHolder objects
 */
var xmlParser = {

  parseXml: function( url, node, element, functie ) {

    var i = 0;       // result counter

    var result = []; // the result array
    /*
     * Open the xml file
     */
    jQuery.get( url, function( data ){

      /*
       * Loop through the results, if we have a filter, apply it.
       */
      jQuery( data ).find( node ).each( function(){
        /*
         * Copy the element holder
         */
        var elementHolder = element.holder;
        var elementData = jQuery(this);

        /*
         * Fill the copied holder with the xml data
         */
        elementData.children().each(function() {
          elementHolder[ this.nodeName ] = jQuery(this).text();
        });

        /*
         * if the filter applies, add the holder to the result
         */
        if( element.filter.test( elementHolder ) ) {
          result[i] = elementHolder; $i++;
        }           

        // console.log( result );

      });

      /*
       * If there is a callback ( prevents the result from parsing before it is ready )
       */
      try {
        if (typeof functie == "undefined") {
          throw 'There is no callback function specified.';
        }
      } catch( e ) { alert( e ); return; }

      functie( result );

    });    

  }

}

第3部分:

呼吁准备好文件:

product.filter.id = 11;

  /*
   * parsen
   */
  var productXml = 'test.xml';
  xmlParser.parseXml( productXml, "product", product, function( data ) {
    console.log( 'result:' );
    console.log( data );
  });

第4部分:

test.xml:

<data>
  <products>
    <product>
      <id>1</id>
      <title>test 1</title>
      <text>text 1</text>
      <price>1.00</price>
    </product>
    <product>
      <id>2</id>
      <title>test 2</title>
      <text>text 2</text>
      <price>2.00</price>
    </product>
    <product>
      <id>3</id>
      <title>test 3</title>
      <text>text 3</text>
      <price>3.00</price>
    </product>
  </products>
</data>

除了一件事,一切正常;

结果会被新创建的持有者覆盖每个循环,有没有人有任何想法如何解决这个问题? (我认为这确实与范围有关)。

谢谢!

2 个答案:

答案 0 :(得分:1)

我找到了解决方案

部分:

var elementHolder = element.holder;

不创建对象的副本,只是另一个引用;

我在此页面上找到了解决方案:

http://my.opera.com/GreyWyvern/blog/show.dml/1725165

Object.prototype.clone = function() {
  var newObj = (this instanceof Array) ? [] : {};
  for (i in this) {
    if (i == 'clone') continue;
    if (this[i] && typeof this[i] == "object") {
      newObj[i] = this[i].clone();
    } else newObj[i] = this[i]
  } return newObj;
};

var elementHolder = element.holder.clone();

答案 1 :(得分:0)

在黑暗中刺伤 - 但我认为你的内循环需要一个闭合。

更改此

elementData.children().each(function() {
  elementHolder[ this.nodeName ] = jQuery(this).text();
});

到这个

elementData.children().each(function( e, n, t ) {
  return function()
  {
    e[n] = t;
  }
}( elementHolder, this.nodeName, jQuery(this).text() ));