主干.js Model.get() 返回 undefined, 范围使用 coffeescript + coffee t

backbone.js Model.get() returns undefined, scope using coffeescript + coffee toaster?

本文关键字:范围 coffeescript coffee undefined Model js get 返回 主干      更新时间:2023-09-26

我正在使用带有咖啡烤面包机的coffeescript(一个很棒的NPM拼接模块)编写一个应用程序,用于构建我的应用程序.js文件。

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

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

@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

但是,尽管记录时控制台中显然存在模型属性,但第二个返回未定义

为了使事情更加有趣,在控制台中手动输入"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 中初始化应用程序控制器,如下所示:

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

请提出建议,谢谢!

这里有两件事需要了解:

  1. fetch是异步的。
  2. 某些console.log是异步的。

所以这就是正在发生的事情:

  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调用用于在控制台中记录内容。

来自 (2) 的console.log带有对fetch填充在 (4) 中的@user的引用;到 (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'))   
)

你会得到你期待的结果。