2013-05-04 46 views
3

我试图调用loadPhotos,但是我得到一个错误,提示loadPhotos没有被定义。我试过this.loadPhotos();,但后来发现一个错误,说对象没有这样的方法。我在这方面很新颖,仍然试图弄清楚什么可以访问什么,以及如果有人能指出我正确的方向,我将不胜感激。我究竟做错了什么?

这里是我的代码:

Album = Backbone.Collection.extend ({ 
    model: Photo, 
    url: "/api/", 
    albumName: "", 
    initialize: function(models, options){ 
     options || (options = {}); 
     if (options.title) { 
      this.albumName = options.title; 
     }; 

     $.ajax({ 
      type: "GET", 
      url: this.url, 
      data: "album=" + this.albumName, 
      dataType: "json", 
      success: function(data){ 
       console.log(data); 
       loadPhotos(data); // <<< the problem is right here 
      }, 
      error: function(jqXHR, textStatus, errorThrown){ 
       console.log("FETCH FAILED: " + errorThrown); 
      } 
     }); 

    }, 

    loadPhotos: function(filenames){ 
     for (var i = 0; i < filenames.length; i++){ 

      var photo = new Photo({fileurl: filenames[i] }); 
      var photoView = new PhotoView({ model: photo}); 
      this.add(photo); 

     } 


    } 


}); 

回答

4

你是误解如何确定范围和在JavaScript this工作。

调用像

loadPhotos(data); 

将寻找一个名为在不同范围loadPhotos从您的成功回调到全球范围内的功能,但是不存在这样的功能,因为该功能连接到您的收藏实例的功能。

this.loadPhotos(data) 

更接近,但完全取决于this引用的内容。 this是JavaScript中的一个特殊关键字,它指向的对象取决于函数的调用方式。在你的情况下,this完全取决于jQuery的行为。您想要使用对集合的引用。通用名称可以更容易地知道变量引用了对象,它们是self,that,有时是_this

做到这一点的一种方法是保存对引用集合的外部this指向的对象的引用。如果你将它保存到一个变量中,它会正常工作。

initialize: function(models, options){ 
    // Stuff 

    var self = this; 

    $.ajax({ 
     type: "GET", 
     url: this.url, 
     data: "album=" + this.albumName, 
     dataType: "json", 
     success: function(data){ 
      console.log(data); 

      // Call the function on the collection. 
      self.loadPhotos(data); 

     }, 
     error: function(jqXHR, textStatus, errorThrown){ 
      console.log("FETCH FAILED: " + errorThrown); 
     } 
    }); 

}, 

另一种选择是做的参宿一@的回答说,并明确使用context属性通过适当的回调上下文。

+0

很好解释,谢谢! – Dmitry 2013-05-04 17:37:33

+3

实际上,设置'$ .ajax'上下文的_easiest_方法就是设置'context'选项...... – Alnitak 2013-05-04 20:29:24

4

如果您直接拨打showPhotos,它将具有全局范围(即window)。

如果你只是this.showPhotos参考它不会工作,要么因为不会建立this被用作背景时,它随后调用。

为了解决这个问题,你还需要问jQuery来设置的this正确的价值,可与context选项来完成:

$.ajax({ 
    ..., 
    context: this, 
    success: this.loadPhotos, 
    error: ... 
}); 

如果你的成功确实什么除了通话loadPhotos,设置context变量允许您直接传递该函数的引用(如上所述),而不是将调用包装到另一个函数体中。