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

时间:2015-01-16 07:13:59

标签: templates knockout.js render highlight.js

我的代码出了问题,即使用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是否应该完全运行? 有一个已知的工作吗?当我使用200ms的超时时,它工作正常,但在我看来这是最糟糕的解决方案。

1 个答案:

答案 0 :(得分: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);
  });
}