javascript - Ractivejs 中的递归部分超出调用堆栈

标签 javascript performance ractivejs

自从发现 Ractivejs 以来,我正在慢慢地将我的应用程序转移到它上面。

在我使用普通 JavaScript 构建 html 树结构来创建元素,然后在完成后将其附加到页面之前。我最近将其转移到 Ractivejs,它在小型树结构中工作得非常好,但如果涉及深度嵌套的对象,它会超出调用堆栈。

有没有一种方法可以将我在 JavaScript 中构建的元素附加到 Ractivejs 模板并在其上保留 Ractivejs 事件,或者有没有一种方法可以递归地循环大对象而不超出调用堆栈?

示例

如何用 JavaScript 构建树

var tree = {
  'childPages' : [{    
    'name': 'first child',
    'childPages': []
  }, {
    'name': 'second child',
    'childPages': [{
       'name': 'second first sub child',
       'childPages': []
     }]
  }, {
    'name': 'third child',
    'childPages': [{
        'name': 'third first sub child',
        'childPages': [{
            'name': 'sub sub child',
            'childPages': []
         }]
     }]
  }]
};


function buildTree (tree) {
  var ul = document.createElement('ul');;
  for(var i =0; i < tree.childPages.length; i++){
    var li = document.createElement('li');
    li.innerText = tree.childPages[i].name;
    ul.appendChild(li);
    if (tree.childPages[i].childPages.length) {
       li.appendChild (buildTree(tree.childPages[i]));
    }
  }
  return ul;
}

document.body.appendChild(buildTree(tree));

如何在 Ractivejs 模板中构建树

var ractive = new Ractive({
  el : 'body',
  template: '#treeNode',
  data: {
'childPages' : [{    
  'name': 'first child',
  'childPages': []
}, {
  'name': 'second child',
  'childPages': [{
    'name': 'second first sub child',
    'childPages': []
  }, {
    'name': 'second second sub child',
    'childPages': []
  }]
}, {
  'name': 'third child',
  'childPages': [{
    'name': 'third first sub child',
    'childPages': [{
      'name': 'sub sub child',
      'childPages': []
    }]
  }]
}]
  }
});
<script src="http://cdn.ractivejs.org/latest/ractive.js"></script>
<script id="treeNode" type="text/ractive">
  <ul>
    {{#each childPages}}
      <li>
         {{name}}
          {{#if childPages}}
           {{> treeNode}}
          {{/if}}
      </li>
     {{/each}}
  </ul>
</script>

最佳答案

通常,当您超出调用堆栈时,这是因为 Ractive 处理丢失数据属性的方式 - 如果您有 {{with foo}}{{bar}}{{/with}}foo.bar不存在,{{bar}}引用未解析,因此它“进入上下文堆栈”,并查找 bar相反。

大多数时候这确实很方便,但在这种情况下可能会出现问题,因为如果树中的某个项目没有 childPages属性,Ractive 会在堆栈中向上到达父级 - 这将我们送入无限递归兔子洞。

有两种解决方案:

  • 确保树中的每个节点都有 childPages属性,即使它是一个空数组,或者...
  • 使用受限引用。如果您使用this.childPages而不仅仅是childPages (或 ./childPages - 这是等效的,您可能对其中一个有审美偏好)然后 Ractive 不会在当前上下文之外查找数据。这是一个例子,其中所有空 childPages数组已删除 - 没有 this. ,我们立即超出了调用堆栈,但因为它在那里,所以我们是完全安全的。

var ractive = new Ractive({
  el : 'body',
  template: '#treeNode',
  data: {
'childPages' : [{    
  'name': 'first child'
}, {
  'name': 'second child',
  'childPages': [{
    'name': 'second first sub child'
  }, {
    'name': 'second second sub child'
  }]
}, {
  'name': 'third child',
  'childPages': [{
    'name': 'third first sub child',
    'childPages': [{
      'name': 'sub sub child'
    }]
  }]
}]
  }
});
<script src="http://cdn.ractivejs.org/latest/ractive.js"></script>
<script id="treeNode" type="text/ractive">
  <ul>
    {{#each this.childPages}}
      <li>
         {{name}}
          {{#if this.childPages}}
           {{> treeNode}}
          {{/if}}
      </li>
     {{/each}}
  </ul>
</script>

关于javascript - Ractivejs 中的递归部分超出调用堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30166473/

相关文章:

java - Java中包类和私有(private)静态内部类的区别?

javascript - 当我追加到数组时,Ractive.js 会追加还是重建所有内容?

java - 简单循环的速度

algorithm - 寻找多维优化算法

javascript - 如何使用 jquery 设置当前窗口大小和位置(因为 body onload 不适用于 asp.net)

javascript - d3 依赖项在 d3 之前加载

javascript - 当数组更改时更新 ractive.js,没有 'magic: true'

mocha.js - 如何使用 sinon 在 mocha 中模拟 ajax 调用而不使用回流存储在响应组件上设置超时

javascript - 在现有 SVG (d3.js v4) 上应用缩放事件

javascript - AngularJS 指令 - 链接功能不触发