knockout.js,afterrender 函数未按预期工作

knockout.js, afterrender function doesnt work as expected

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

<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 毫秒的超时时,它工作正常,但这是我认为最糟糕的解决方案。

您的 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);
  });
}