【问题标题】:knockout.js, afterrender function doesnt work as expectedknockout.js,afterrender 函数无法按预期工作
【发布时间】:2015-01-16 17:19:39
【问题描述】:

我的代码有问题,我正在使用 hljs 突出显示我正在使用的代码 sn-ps。我写了一个模板系统,例如一般输入是这样的:

<codeexample params="type: html">
  <div style="example_class">Example code</div>
</codeexample>

我的模板解释器:

<template id="codeexample">
  <div class="code">
    <pre><code data-bind="attr: {class: type}, template: { nodes: $componentTemplateNodes, afterRender: $root.handleCode}, visible: false ">
    </code></pre>
  </div>
</template>

我的handleCode函数:

this.handleCode = function(element) {
  var preCodeTags = $(element).find('pre code');
  preCodeTags.each(function(i, block) {
    hljs.highlightBlock(block);
    block.show(100);
  });
}

问题是在模板渲染到我的实际模板之前已经调用了 afterRender 函数,我曾经添加一个console.log($(element).find('pre code'));,结果长度为0。

[prevObject: jQuery.fn.jQuery.init[3], context: undefined, selector:
"pre code", constructor: function, init: function…] 
context: undefined
length: 0

函数afterRender 是否应该在渲染过程之后运行? 有没有已知的工作?当我使用 200 毫秒的超时时,它工作正常,但在我看来这是最糟糕的解决方案。

【问题讨论】:

  • 请在 jsfiddle 中创建一个 repro!还请在您的问题中包含您的codeexample 组件定义!为什么你使用的是哪个 KO 版本? $componentTemplateNodes还没有正式发布... 3.3版本会包含
  • 添加小提琴可能有点困难,因为我在单个页面应用程序上使用 html 导入,其中每个页面都有自己的模板文件。你是对的,我包括 3.3alpha,因为我想使用嵌套组件。

标签: templates knockout.js render highlight.js


【解决方案1】:

您的afterRender 处理程序不太正确。参数(在您的情况下为element)实际上是一个所有渲染元素的数组。来自the documentation

viewModel.myPostProcessingLogic = function(elements) {
    // "elements" is an array of DOM nodes just rendered by the template
    // You can add custom post-processing logic here
}

所以它没有成功找到code 元素。你可以这样做:

this.handleCode = function(elements) {
  var preCodeTags = $(elements).filter('div').find('pre code');
  preCodeTags.each(function(i, block) {
    hljs.highlightBlock(block);
    block.show(100);
  });
}

【讨论】:

  • 感谢您的回答,这可能不起作用,在这种情况下它也不会过滤任何预代码标签。
  • @Grief-Code 你能 console.log 参数本身而不是你的 jQuery $().find 围绕它 - 仔细检查你正在传递的内容吗?
  • 好的,它返回给我一个数组:[text, div, text] 第一个 div 包括这个:&lt;code data-bind="template: { nodes: $componentTemplateNodes, afterRender: $root.handleCode}, attr: {class: type.length &gt; 0 ? type : ''}" class="html"&gt;↵ &lt;div style="example"&gt;I'm an example element!&lt;/div&gt;↵ &lt;/code&gt; 看起来像我真正想要的。
  • @Grief-Code 谢谢 - 更新了答案。它现在过滤数组以仅获取div,然后像以前一样获取finds 和pre code
  • 感谢您的帮助,我花了几分钟时间,但&lt;code&gt; 标签的实际选择器是这个$(elements).filter('div').parent() 我只有一个小错误,但这与问题无关。
猜你喜欢
  • 2018-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多