1

<canvas>将绘图插入车把模板的最佳方法是什么?请参见下面的示例。我的第一个尝试是canvas-inline辅助函数,它使用 JavaScsript 创建一个画布对象,然后返回它。遗憾的是,我在模板中看到的只是“[object HTMLCanvasElement]”。Handlebars 需要一个 HTML 文本字符串!

所以,我的第一个问题是:有没有办法将现成的 DOM 对象返回给 Handlebars 对象?如果不是,它是一个简单的 hack,还是完全违背 Handlebars 在引擎盖下的工作方式?

我的第二次尝试是canvas-timer辅助功能。这只是返回一个<canvas>字符串,然后使用 100 毫秒超时去添加画布内容。这行得通,但我不喜欢 Fragility 先生现在加入团队的事实(穿着他的“我爱魔术数字”T 恤)。

所以,如果我的前两个问题的答案是“否”和“否”,那么有没有一种使用后一种方法的好方法,但摆脱了计时器和任意 100 毫秒的猜测?也就是说,Javascript 代码将在<canvas>元素出现时运行,而不是之前,而不是之后。注意:我想要一些封装在辅助函数中的东西。

在这里摆弄:http: //jsfiddle.net/HCQSt/

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Handlebars: canvas test</title>
<script src="js/jquery-1.10.2.js"></script>
<script src="js/handlebars.js"></script>

<!--- ******************** TEMPLATES ********************  -->

<script id="test-template" type="text/x-handlebars-template">
<h3>Hello {{world}}</h3>
{{{canvas-inline col}}}
{{{canvas-timer col}}}
</script>

<!--- ******************** ************ ********************  -->

<script language="javascript">
Handlebars.registerHelper("canvas-inline", function(col) {
var canvas  = document.createElement('canvas');
if(canvas){
    console.log(canvas);
    canvas.width=128;canvas.height=128;
    var ctx = canvas.getContext('2d');
    ctx.fillStyle = col;
    ctx.fillRect(0,80,128,16);
    ctx.fillRect(16,0,32,32);
    ctx.fillRect(80,0,32,32);
    }
else console.log("no canvas object");
return canvas;
});

Handlebars.registerHelper("canvas-timer", function(col) {
setTimeout(function(){
    //var canvas    = document.createElement('canvas');
    var canvas  = $('#xxx')[0];
    if(canvas){
        console.log(canvas);
        canvas.width=128;canvas.height=128;
        var ctx = canvas.getContext('2d');
        ctx.fillStyle = col;
        ctx.fillRect(0,80,128,16);
        ctx.fillRect(16,0,32,32);
        ctx.fillRect(80,0,32,32);
        }
    else console.log("no canvas object");
    },100);
return '<canvas id="xxx"></canvas>';
});


var T=Handlebars.compile ( $("#test-template").html() );

$(function(){   //onReady
var obj={ world:"Blue-Green Planet", col:"#f33" };
$('<div class="view" id="test1">').append(T(obj)).appendTo('#views');
});
</script>

</head>
<body>
<h1>Handlebars: canvas test</h1>

<div id="views"></div>

</body>
</html>

PS如果你的问题是“你为什么要这样做?”,我的回答是“二维码”。提供给模板的 URL 的 QR 码。(在这种特殊情况下,我有一个表格解决方法,但我确信情况并非总是如此。)

4

1 回答 1

4

助手主要用于生成进入视图的内容,因此当助手被触发时,这是在视图插入页面之前。当您的助手依赖于现有的视图元素时,您会遇到时间问题。(这就是你的魔法超时有效的原因)。

另一种方法是使用图像而不是画布,并让助手生成数据 url。

小提琴:http: //jsfiddle.net/gwwar/L7TqJ/2/

<script id="test-template" type="text/x-handlebars-template">
    <h3>Hello {{world}}</h3>
    <img src="{{{generateQRCode col}}}"/>
</script>


Handlebars.registerHelper("generateQRCode", function (col) {
    var canvas = window.document.createElement("canvas");
    canvas.width = 128;
    canvas.height = 128;
    var ctx = canvas.getContext('2d');
    ctx.fillStyle = col;
    ctx.fillRect(0, 80, 128, 16);
    ctx.fillRect(16, 0, 32, 32);
    ctx.fillRect(80, 0, 32, 32);
    return canvas.toDataURL();
});

var T = Handlebars.compile($("#test-template").html());

$(function () { //onReady
    var obj = {
        world: "Blue-Green Planet",
        col: "green"
    };
    $('<div class="view" id="test1">').append(T(obj)).appendTo('#views');
});

觉得这还是太乱了?

您可能还想尝试使用 ember,它使用把手作为其视图层,并在插入视图时触发事件。

编辑:我意识到我提出的解决方案之一可以放入助手中。

于 2013-09-26T03:09:35.380 回答