为什么在访问模型时,backbone.js 返回一个空数组?

发布于 2025-01-07 03:26:12 字数 805 浏览 1 评论 0原文

我有一个路由器访问其集合。我的 for 循环没有迭代模型,因此我尝试记录集合以查看它返回的内容。事实证明,当我直接记录集合时,我会按预期看到所有模型。但是,如果我尝试记录集合的 models 属性,我会得到一个空数组!这没有道理。这些线直接彼此相连。我尝试更改顺序并得到相同的结果。

console.log(this.collection);
=> Shots
    _byCid:    Object
    _byId:     Object
    length:    15
    models:    Array[15]
    __proto__: Shots
    ...

console.log(this.collection.models);
=> []

console.log(this.collection.length);
=> 0

为什么会出现这种情况呢?

以下是路由器中的代码,可以更好地了解该代码的触发位置:

# Routers
class Draft.Routers.Shots extends Backbone.Router
  routes:
    ''            : 'index'
    'shots/:id'   : 'show'

  initialize: ->
    @collection = new Draft.Collections.Shots()
    @collection.fetch()

  index: ->
    console.log @collection
    console.log @collection.models

I have a router accessing its collection. My for loop wasn't iterating through the models so I tried logging the collection to see what it returned. Turns out when I log the collection directly I see all of the models as expected. But if I try to log the models attribute of the collection I get an empty array! It doesn't make sense. These lines are directly following each other. I tried changing the order and got the same outcome.

console.log(this.collection);
=> Shots
    _byCid:    Object
    _byId:     Object
    length:    15
    models:    Array[15]
    __proto__: Shots
    ...

console.log(this.collection.models);
=> []

console.log(this.collection.length);
=> 0

Why would this happen?

Here is the code as it is in the router to give a better context of where this code is firing:

# Routers
class Draft.Routers.Shots extends Backbone.Router
  routes:
    ''            : 'index'
    'shots/:id'   : 'show'

  initialize: ->
    @collection = new Draft.Collections.Shots()
    @collection.fetch()

  index: ->
    console.log @collection
    console.log @collection.models

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

初熏 2025-01-14 03:26:12

吉姆,

这并不能解决你的问题——你已经解决了这个问题。但它解释了为什么您会看到控制台输出。

当您运行 console.log(this) 时,您将输出对象本身,并且控制台将引用(如果您愿意,可以是指针)链接到内部变量。

当您在控制台中查看它时,在 console.log(this) 运行时,模型区域是空的,但是当您查看时日志中,集合已完成加载模型并且内部数组变量已更新,并且对象日志中对该变量的引用显示当前内容。

基本上在 console.log(this) 中,内部模型变量继续其正常生命周期,控制台显示您查看它时的当前状态,而不是您调用它时的状态。
使用console.log(this.models),数组按原样转储,不保留引用,所有内部值都一一转储。

这种行为很容易在很短的超时时间内重现,请参阅this fiddle.. http://jsfiddle.net/bendog/XVkHW/

Jim,

This doesn't fix your problem - you've worked that out. But it explains why you're seeing the console output you see.

When you run console.log(this), you output the object itself and the console links references (pointers if you like) to the inner variables.

When you're looking at it in the console, at the time the console.log(this) runs the models area is empty, but at the time you look at the logs, the collection has finished loading the models and the inner array variable is updated, AND the reference to that variable in the object log shows the current content.

Basically in console.log(this),inner models variable continues its normal life and the console shows the current status at the time you're looking at it, not at the time you called it.
With console.log(this.models), the array is dumped as is, no reference is kept and all the inner values are dumped one by one..

That behaviour is quite simple to reproduce with a short timeout, see this fiddle.. http://jsfiddle.net/bendog/XVkHW/

与酒说心事 2025-01-14 03:26:12

我发现我需要监听集合来重置。因此,我没有将模型传递到视图中,而是创建了另一个需要集合的视图,并侦听“重置”事件以触发视图的“渲染”。

# Routers
class Draft.Routers.Shots extends Backbone.Router
  routes:
    ''            : 'index'
    'shots/:id'   : 'show'

  initialize: ->
    @collection = new Draft.Collections.Shots()
    @collection.fetch()

  index: ->
    view = new Draft.Views.Desktop(collection: @collection)

# Views
class Draft.Views.Desktop extends Backbone.View
  el: $("body")

  initialize: ->
    @collection.on("reset",@render,this)

  render: ->
    console.log @collection
    console.log @collection.length

I found that I needed to listen for the collection to reset. So instead of passing the model into the view I created another view expecting the collection and listened for the 'reset' event to fire 'render' for the view.

# Routers
class Draft.Routers.Shots extends Backbone.Router
  routes:
    ''            : 'index'
    'shots/:id'   : 'show'

  initialize: ->
    @collection = new Draft.Collections.Shots()
    @collection.fetch()

  index: ->
    view = new Draft.Views.Desktop(collection: @collection)

# Views
class Draft.Views.Desktop extends Backbone.View
  el: $("body")

  initialize: ->
    @collection.on("reset",@render,this)

  render: ->
    console.log @collection
    console.log @collection.length
贪了杯 2025-01-14 03:26:12

您可以使用承诺。 (.done 就可以了)

@collection.fetch().done =>
  for model in @collection.models
    console.log model

这将为您提供 @collection 的模型,并准备好使用。

或者如果您不需要强制应用程序等待,

@collection.on 'sync', =>
  for model in @collection.models
    console.log model

这两种方法都可以让您执行您想要的操作。

You can use a promise. (.done will do fine)

@collection.fetch().done =>
  for model in @collection.models
    console.log model

this will give you @collection's models fetched and ready to go.

or if you don't need to force the app to wait,

@collection.on 'sync', =>
  for model in @collection.models
    console.log model

Both of these will let you do what you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文