参考Ractive.js中的子属性

时间:2016-05-10 15:28:58

标签: javascript ractivejs

Ractive.js的新手,在阅读了文档之后,我仍然挂了一些语法。我的示例在我的数组中为每个元素创建一个canvas标记,然后为每个元素实例化一个自定义类的 distinct 对象来处理动画。如评论中所述,我犯了三个错误。

在事件处理程序中,我想引用height属性(在我的数组中定义),但this.get(repeater.height)和this.repeater.height都不起作用。我还想调用与该事件关联的对象的方法,但是使用this.myCustomClass.setFrame()也不起作用。

当我尝试引用canvas的方法时,我的动画类代码中至少出现一个错误:this.canvas.getContext()其中“canvas”是我传入的id对象构造函数。

很明显,我误解了如何引用Ractive实例的子属性。这里有什么帮助?

var repeater = [
    {id: "stalkerOne", width: 225, height: 432, left: 8, spriteSheetURL: "spriteSheets/stalkerone.jpg", rows: 5, columns: 5, totalFrames:  24},
    {id: "stalkerTwo", width: 175, height: 432, left: 230, spriteSheetURL: "spriteSheets/stalkertwo.jpg", rows: 6, columns: 5, totalFrames:  26},
    {id: "stalkerThree", width: 251, height: 432, left: 404, spriteSheetURL: "spriteSheets/stalkerthree.jpg", rows: 6, columns: 5, totalFrames:  28}
]

var CanvasAnimation = Ractive.extend( {
    oninit: function() {
        this.get('repeaters').forEach(function(repeater){
            var myCanvasSprite = new CanvasSprite(repeater.id, repeater.width, repeater.height, repeater.spriteSheetURL, repeater.rows, repeater.columns, repeater.totalFrames);
            myCanvasSprite.setFrame(0);
            //this.canvas.getContext() throwing error in class code
        });

        this.on('setFrame', function (event) {
            var offsetY = event.original.clientY - event.node.getBoundingClientRect().top;
            var relY = offsetY/this.get(repeater.height); //why doesn't this.get() work here?
            this.myCanvasSprite.setFrame(relY); //custom class method not working either...
        });
    }
});       

var canvasAnimation = new CanvasAnimation({
    el: '#container',
    template: '#template',
    data: { repeaters: repeater }
});

1 个答案:

答案 0 :(得分:0)

我认为您缺少的是将CanvasSprite对象数组添加到Ractive数据,然后使用事件上下文获取当前精灵(有关完整示例,请参阅https://jsfiddle.net/martypdx/srbvekc4/2/):

var CanvasAnimation = Ractive.extend( {
    template: `
        {{#each sprites}}
            <li on-click='setFrame'>{{.id}}</li>
        {{/each}}`,
    oninit() {
        var sprites = this.get('repeaters').map( function(repeater){    
            return new CanvasSprite(repeater.id, repeater.width, repeater.height, repeater.spriteSheetURL, repeater.rows, repeater.columns, repeater.totalFrames);
        });

        // add the class instances to the data
        this.set( 'sprites', sprites );

        this.on('setFrame', function (event) {
            // here's how we get the sprite from the event
            var sprite = event.context;
            var offsetY = event.original.clientY - event.node.getBoundingClientRect().top;
            var relY = offsetY/sprite.height;
            sprite.setFrame(relY);
        });
    },
    onrender() {
        // wait till render, otherwise nothing there!
        this.get( 'sprites' ).forEach( sprite => sprite.setFrame(0) );
    }
});  

编辑:您还可以使用组件更好地封装每个精灵(请参阅https://jsfiddle.net/martypdx/srbvekc4/1/):

var CanvasAnimation = Ractive.extend( {
    template: `
        {{#each repeater}}
            <Sprite options='{{this}}'></Sprite>
        {{/each}}`
});    

var Sprite = Ractive.extend({
    template: `<li on-click='setFrame'>{{sprite.id}}</li>`,
    oninit() {
        const sprite = new CanvasSprite( repeater.id, repeater.width, repeater.height, repeater.spriteSheetURL, repeater.rows, repeater.columns, repeater.totalFrames );

        // since example template is using properties from sprite,
        // we add it to the data
        this.set( 'sprite',  sprite );

        this.on('setFrame', function (event) {
            var offsetY = event.original.clientY - event.node.getBoundingClientRect().top;
            var relY = offsetY/sprite.height;
            sprite.setFrame(relY);
        });
    },
    onrender() {
        this.sprite.setFrame(0);
    }
});

var canvasAnimation = new CanvasAnimation({
    el: document.body,
    template: '#template',
    data: { repeaters: repeater },
    components: { Sprite }
});

更新:使用多参数构造函数,如果组件处理CanvasSprite的实例化,也可以实现更好的封装。