我应该如何确保已加载反应性 DOM 元素?
How should I make sure that a reactive DOM element has been loaded?
我有一个显示图像的模板 image
。图片显示在 canvas
和 img
标签之间切换,具体取决于用户是刚刚创建图片还是已经在服务器上。
我使用名为 pageSession
的反应字典在 img
和 canvas
之间切换,我在其中存储了一个名为 displayMode
的布尔反应变量。我有一个助手 currentDisplayMode
用于 return displayMode
值。
所以助手看起来像这样:
Template.image.helpers({
"currentDisplayMode" : function(){
return pageSession.get ("displayMode");
}
});
在我的模板中,我根据 currentDisplayMode
加载 canvas
或 img
,如下所示:
{{#if currentDisplayMode}}
<img src="{{source}}"width="215" height="215"/>
{{else}}
<canvas id="canvas" width="215" height="215"></canvas>
{{/if}}
1.问题.
如果我尝试这样的事情:
pageSession.set("displayMode", false)
var canvas = template.find('#canvas')
//do stuff related to canvas
我找不到我的 canvas 因为 UI 还没有更新。
2。我的脏修复
我用这样的 Meteor.setTimeout()
来修复它:
pageSession.set("displayMode", false)
Meteor.setTimeout(function(){
var canvas = template.find('#canvas')
//do stuff related to canvas
}, 100);
3。我的问题
此修复目前有效,但我担心 100 毫秒不足以更新 UI 的情况。而且,我觉得这不是一个可靠的解决方案。
请注意,它不仅仅是二进制切换(图像或canvas)。 canvas 需要根据 3 种不同的模式(identicon、photo、imageFile)重新渲染。每种模式也可以重新渲染。
总而言之,我需要在几种情况下正确填写我的canvas(一旦我确定它之前已经渲染过):
- 当
displayMode
切换时:从 <img>
到 <canvas>
- 当我用另一种方法填充我的 canvas 时:例如从识别图标到照片
- 当我用相同的方法但不同的数据填充 canvas 时:例如我重新加载另一个 identicon 或我加载另一张照片。
你将如何进行?
我尝试了另外两种方法,都是通过将 canvas 移动到专用模板中:
Blaze.render()
目标中的模板 div 并附加到 canvas 模板 rendered
函数我的代码。这使得控制加载或未加载的内容变得困难:我需要删除以前呈现的 canvas 模板。
- 这里解释的解决方法:Meteor: Forcing rerendering whole template after collection update with Blaze 也没有用(我没有努力尝试,它看起来不像是一个干净的解决方法)。
我终于设法解决了这个问题。基本上,我想要的是确保在执行我的 3 个填充任务(identicon、照片、图像文件)之一之前渲染了我的 canvas。
第一步很简单:我使用页面会话反应变量标志 canvasLoaded
,我在 rendered
和 destroyed
canvas 模板函数上更新了它。
第二步是我已经用来确保在表单提交时上传了文件(并且它的 url 可用)的东西。这是我在这里找到的 waitfor
函数:
所以我要做的是等待我的标志 canvasLoaded
在 waitfor
函数中切换为 true。在 waitfor
的回调中,我只是调用了一个 loadCanvas
函数,我根据当前的填充模式和参数(全部存储在反应字典变量中)加载 canvas。
瞧瞧! :-)
我有一个显示图像的模板 image
。图片显示在 canvas
和 img
标签之间切换,具体取决于用户是刚刚创建图片还是已经在服务器上。
我使用名为 pageSession
的反应字典在 img
和 canvas
之间切换,我在其中存储了一个名为 displayMode
的布尔反应变量。我有一个助手 currentDisplayMode
用于 return displayMode
值。
所以助手看起来像这样:
Template.image.helpers({
"currentDisplayMode" : function(){
return pageSession.get ("displayMode");
}
});
在我的模板中,我根据 currentDisplayMode
加载 canvas
或 img
,如下所示:
{{#if currentDisplayMode}}
<img src="{{source}}"width="215" height="215"/>
{{else}}
<canvas id="canvas" width="215" height="215"></canvas>
{{/if}}
1.问题.
如果我尝试这样的事情:
pageSession.set("displayMode", false)
var canvas = template.find('#canvas')
//do stuff related to canvas
我找不到我的 canvas 因为 UI 还没有更新。
2。我的脏修复
我用这样的 Meteor.setTimeout()
来修复它:
pageSession.set("displayMode", false)
Meteor.setTimeout(function(){
var canvas = template.find('#canvas')
//do stuff related to canvas
}, 100);
3。我的问题
此修复目前有效,但我担心 100 毫秒不足以更新 UI 的情况。而且,我觉得这不是一个可靠的解决方案。
请注意,它不仅仅是二进制切换(图像或canvas)。 canvas 需要根据 3 种不同的模式(identicon、photo、imageFile)重新渲染。每种模式也可以重新渲染。
总而言之,我需要在几种情况下正确填写我的canvas(一旦我确定它之前已经渲染过):
- 当
displayMode
切换时:从<img>
到<canvas>
- 当我用另一种方法填充我的 canvas 时:例如从识别图标到照片
- 当我用相同的方法但不同的数据填充 canvas 时:例如我重新加载另一个 identicon 或我加载另一张照片。 你将如何进行?
我尝试了另外两种方法,都是通过将 canvas 移动到专用模板中:
Blaze.render()
目标中的模板 div 并附加到 canvas 模板rendered
函数我的代码。这使得控制加载或未加载的内容变得困难:我需要删除以前呈现的 canvas 模板。- 这里解释的解决方法:Meteor: Forcing rerendering whole template after collection update with Blaze 也没有用(我没有努力尝试,它看起来不像是一个干净的解决方法)。
我终于设法解决了这个问题。基本上,我想要的是确保在执行我的 3 个填充任务(identicon、照片、图像文件)之一之前渲染了我的 canvas。
第一步很简单:我使用页面会话反应变量标志 canvasLoaded
,我在 rendered
和 destroyed
canvas 模板函数上更新了它。
第二步是我已经用来确保在表单提交时上传了文件(并且它的 url 可用)的东西。这是我在这里找到的 waitfor
函数:
所以我要做的是等待我的标志 canvasLoaded
在 waitfor
函数中切换为 true。在 waitfor
的回调中,我只是调用了一个 loadCanvas
函数,我根据当前的填充模式和参数(全部存储在反应字典变量中)加载 canvas。
瞧瞧! :-)