[英]How to refer to DOM Elements When Using Ractive.extend()?
因此,如果我使用Ractive.extend()来实例化自定义类的对象,那么我将如何引用该类中的DOM元素? 我显然不能像往常一样使用document.getElementById(),因为尚未呈现DOM并且将Ractive.findComponent()传递给我的构造函数返回“Ractive.findComponent不是函数”。 我想做的是这样的:
class myClass {
constructor(id /*,...*/) {
this.element = document.getElementById(id); //how do I do this??
};
};
var Extended = Ractive.extend( {
oninit() {
var myObject = new myClass(id /*,...*/);
this.set({myObject});
}
});
var ractiveExtended = new Extended({
el: document.body,
template: '#template',
data: { id: myId}
});
ETA:这也不起作用......
class myClass {
constructor(id /*,...*/) {
this.element = document.getElementById(id);
};
};
var Extended = Ractive.extend( {
onrender() {
var myObject = new myClass(id /*,...*/);
this.set({myObject});
}
});
var ractiveExtended = new Extended({
el: document.body,
template: '#template',
data: { id: myId}
});
这也不是......
class myClass {
constructor(id /*,...*/) {
this.element = id;
this.element.innerHTML = 'Hello world!';
};
};
var Extended = Ractive.extend( {
onrender() {
var myObject = new myClass(document.getElementById(id) /*,...*/);
this.set({myObject});
}
});
var ractiveExtended = new Extended({
el: document.body,
template: '#template',
data: { id: myId}
});
更新了评论中阐明的问题的答案
你这里有一个鸡蛋问题:
{{#each sprites}}
<canvas id={{.id}}></canvas>
{{/each}}
表示Ractive将为sprites
每个项创建<canvas>
并为其分配适当的ID。 但是,初始渲染时未定义sprites
,因此不会创建<canvas>
元素。
然后,在onrender()
内部创建类的实例,假设<canvas>
元素已经存在。 只有在那之后你才将实例添加到sprites
,告诉Ractive渲染元素:
this.set({ sprites });
有几种可能的解决方案。 (我认为)最好的方法是在你的类中添加一个render()
方法,并将任何与DOM相关的东西移出构造函数。 然后您的代码将更改为以下内容:
onrender () {
var sprites = this.get('repeaters').map(function(repeater){
return new CanvasSprite(repeater.id);
});
this.set({ sprites });
sprites.forEach(function (sprite) {
sprite.render();
});
}
但是,如果您不想修改类,则只需使用现有的repeaters
数组进行{{each}}
循环。 在这里演示: http : //jsfiddle.net/9xLzj3zd/1/
关键是,在使用document.getElementsById()
或类似方法之前,需要一种方法告诉Ractive渲染<canvas>
元素。
原始答案
如果需要访问DOM,请将初始化代码从oninit
移动到onrender
。 然后,您可以使用document.getElementById()
或ractive.find()
( 此处的文档 )来获取所需的元素。
class myClass {
constructor(id) {
this.element = document.getElementById(id);
this.element.innerHTML = 'Hello world!';
};
};
var Extended = Ractive.extend( {
onrender() {
// use this.get('id') to get ID from Ractive's data
var myObject = new myClass(this.get('id'));
this.set({myObject});
}
});
var ractiveExtended = new Extended({
el: document.body,
template: '#template',
data: { id: 'content' },
});
编辑:完整运行示例: http : //jsbin.com/vuziyepeku/edit?html,js,output
我会将每个CanvasSprite
封装在它自己的组件中:
const CanvasSpriteComponent = Ractive.extend({
template: '#sprite',
// Using onrender, not oninit, because we need DOM canvas node
onrender(){
const canvas = this.find('canvas');
const repeater = this.get('repeater');
var sprite = new CanvasSprite(canvas, repeater.width, repeater.height, repeater.spriteSheetURL, repeater.rows, repeater.columns, repeater.totalFrames);
sprite.left = repeater.left; //add variables *not* in the constructor
sprite.setFrame(0);
this.on('setFrame', function (event) {
var offsetY = event.original.clientY - event.node.getBoundingClientRect().top;
var relY = offsetY/sprite.height;
sprite.setFrame(relY);
});
}
});
然后在主实例中使用它:
var CanvasAnimation = Ractive.extend( {
template: '#animation',
components: {
'canvas-sprite': CanvasSpriteComponent
}
});
var canvasAnimation = new CanvasAnimation({
el: 'main',
data: { repeaters: repeater }
});
可以说,它更有意义为您CanvasSprite
类采取帆布节点,因为那是不再依赖于该节点如何定位(目前document.getElementById
)。
如果您根本不愿意更改该类,则只需要构成一个唯一的id(如果转发器集合不会变异,则使用索引)。 在这种情况下,我重用组件的唯一ID:
const CanvasSpriteComponent = Ractive.extend({
// ...
onrender(){
const canvas = this.find('canvas');
canvas.id = `canvas-${this._guid}`
const repeater = this.get('repeater');
var sprite = new CanvasSprite(canvas.id, repeater.width, repeater.height, repeater.spriteSheetURL, repeater.rows, repeater.columns, repeater.totalFrames);
sprite.left = repeater.left; //add variables *not* in the constructor
sprint.setFrame(0);
this.on('setFrame', function (event) {
var offsetY = event.original.clientY - event.node.getBoundingClientRect().top;
var relY = offsetY/sprite.height;
sprite.setFrame(relY);
});
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.