backbone.js Model.get()使用coffeescript + coffee toaster返回undefined,scope?

时间:2012-06-08 06:32:47

标签: javascript backbone.js coffeescript scoping

我正在使用coffeescript编写一个应用程序,用咖啡烤面包机(一个非常棒的NPM模块进行拼接)来构建我的app.js文件。

我的许多应用程序类和模板需要有关当前用户的信息,所以我有一个类User(扩展Backbone.Model)的实例存储为我的主Application类的属性(扩展Backbone.Router)。

作为初始化例程的一部分,我从服务器中获取用户(负责身份验证,角色,帐户切换等)。这是coffeescript:

@user = new models.User
@user.fetch()
console.log(@user) 
console.log(@user.get('email'))   

第一个日志记录语句在控制台中输出正确的Backbone.Model属性对象:

User
_changing: false
_escapedAttributes: Object
_pending: Object
_previousAttributes: Object
_silent: Object
attributes: Object
  account: Object 
  created_on: "1983-12-13 00:00:00"
  email: "ben@accomplicecreative.com"
  icon: "0"
  id: "1"
  last_login: "2012-06-07 02:31:38"
  name: "Ben Ipsen"
  roles: Object
__proto__: Object
changed: Object
cid: "c0"
id: "1"
__proto__: ctor
app.js:228

然而,第二个返回 undefined ,尽管记录时控制台中的模型属性明显存在。

只是为了让事情变得更有趣,在控制台中输入“window.app.user.get('email')”会手动返回“ben@accomplicecreative.com”的预期值......?

仅供参考,以下是initialize方法如何编译到我的app.js文件中:

Application.prototype.initialize = function() {
  var isMobile;
  isMobile = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/);
  this.helpers = new views.DOMHelpers().initialize().setup_viewport(isMobile);
  this.user = new models.User();
  this.user.fetch();
  console.log(this.user);
  console.log(this.user.get('email'));
  return this;
};

我在静态HTML中初始化Application控制器,如下所示:

jQuery(document).ready(function(){
   window.app = new controllers.Application();
});

建议请谢谢!

1 个答案:

答案 0 :(得分:3)

您需要了解两件事:

  1. fetch是异步的。
  2. 有些console.log是异步的。
  3. 所以这就是发生的事情:

    1. 您致电@user.fetch()并启动AJAX通话。
    2. 你调用console.log(@user),这会做另一点异步工作但是(这是一个很大的但是!),它需要引用@user,当引用时,引用将被取消引用console.log调用会进行日志记录。
    3. 您致电console.log(@user.get('email')),这会带来@user.get('email') 返回的内容,get电话会立即执行。
    4. 来自(1)的AJAX调用会为@user返回一些内容。
    5. console.log调用可以在控制台中记录内容。
    6. 来自(2)console.log带有@user的引用,fetch填充在(4);当(4)执行时,@user已填充,因此您在控制台中看到一个完整的用户。当您在(3)中致电@user.get('email')时,fetch尚未填充@user,因此@user.get('email')undefined并且您实际上是在说

      console.log(undefined)
      

      console.log调用的参数将被评估(但传递给console.log的最终结果将不会被解除引用!)当您调用函数而不是它完成执行并放入内容时控制台。

      所以你有各种异步的东西混合在一起,其中就是混乱。

      如果您将代码更改为:

      @user = new models.User
      @user.fetch(success: =>
          console.log(@user) 
          console.log(@user.get('email'))   
      )
      

      你会得到你期待的结果。