我应该如何重写这段代码

时间:2012-05-24 17:34:32

标签: javascript backbone.js

这些函数(*)和(**)位于Backbone.View内,但我认为不需要Backbone的知识来解决这个问题。

正如您在代码中的评论中所看到的那样: 1)我调用getAvatar函数一切正常,
2)当getAvatar调用setAvatar时某些内容被破坏

我该如何解决以下问题?


(*)

    getAvatar: function ()
    {
        var creatorIds = this.getCreatorIds();
        console.log(creatorIds); // [1,2]  ******  here is ok *******

        for (var c = 0, l = creatorIds.length; c < l; c += 1) {
            if (typeof this.avatars[creatorIds[c]] === 'undefined') {
                this.userModel = new UserModel({id: creatorIds[c]});
                this.userModel.fetch();
                this.userModel.on('change', this.setAvatar, this);      
            }
        }
    },

(**)

    setAvatar: function ()
    {       
        console.log(this.userModel.get('id')); // 2, 2  *********  it should be 1, 2  *******
        this.names[this.userModel.get('id')] = this.userModel.get('name');
        this.avatars[this.userModel.get('id')] = typeof this.userModel.get('avatar');
        this.render();
    },

* 的)

initialize: function ()
{
     _.bindAll(this, 'getAvatar', 'setAvatar');
}

2 个答案:

答案 0 :(得分:1)

看起来backbone.js为on

的上下文提供了第三个参数
object.on(event, callback, [context])

您的代码将是

getAvatar: function ()
{
    var creatorIds = this.getCreatorIds();
    console.log(creatorIds); // [1,2]  ******  here is ok *******

    for (var c = 0, l = creatorIds.length; c < l; c += 1) {
        if (typeof this.avatars[creatorIds[c]] === 'undefined') {
            this.userModel = new UserModel({id: creatorIds[c]});
            this.userModel.fetch();
            this.userModel.on('change', this.setAvatar, this );  //added this after the function.
        }
    }
},

或者您可以使用闭包

getAvatar: function ()
{
    var that = this;  //variable to maintain scope
    var creatorIds = this.getCreatorIds();
    console.log(creatorIds); // [1,2]  ******  here is ok *******

    for (var c = 0, l = creatorIds.length; c < l; c += 1) {
        if (typeof this.avatars[creatorIds[c]] === 'undefined') {
            this.userModel = new UserModel({id: creatorIds[c]});
            this.userModel.fetch();
            this.userModel.on('change', function(){ that.setAvatar(); } );  //use a closure here with that variable that which is defined above.    
        }
    }
},

答案 1 :(得分:1)

问题是你要分配两次相同的变量。在getAvatar()中,您首先将this.userModel设置为具有id == 1的UserModel。然后在下一个循环迭代中,将为其分配ID为== 2的UserModel。

setAvatar()函数被点击时,它将查看this.userModel,并且只能看到您设置的一个值。您应该尽量不使用实例变量来存储模型。

这是修复它的一种方法。可能有更简单的方法来修复它,但很难从给出的代码示例中分辨出来。我还添加了一些关于代码中一些奇怪内容的评论。

(*)

getAvatar: function ()
{
    var creatorIds = this.getCreatorIds();
    console.log(creatorIds); // [1,2]  ******  here is ok *******

    var self = this;

    for (var c = 0, l = creatorIds.length; c < l; c += 1) {
        if (typeof this.avatars[creatorIds[c]] === 'undefined') {
            var user = new UserModel({id: creatorIds[c]});

            //probably better to bind the handler first, in case fetch() completes synchronously from cache
            user.on('change', function(){
                console.log(user.get('id'));
                self.names[user.get('id')] = user.get('name');
                self.avatars[user.get('id')] = typeof user.get('avatar'); //are you sure you want typeof here?
                self.render(); //Note, this will get called a lot. Are you sure you want to do this?
            });   

            user.fetch();   
        }
    }
}