Backbone 收藏中消失的模型

发布于 2024-12-10 13:54:18 字数 2580 浏览 0 评论 0原文

我有一个 Backbone 模型 line,其中包含模型 Stop 的集合。 在某些时候,我想使用 Underscore 函数 reduce 遍历线路中的站点并获取沿线的总行程时间。

然而,这不起作用。似乎这个系列在某个时刻发生了一些变化。 它似乎只包含一个没有有意义属性的对象,尽管我知道它已经填充了四个具有有效属性的停止模型。

模型:

App.models.Line = Backbone.Model.extend({
    initialize: function() {
        var stops = new App.models.Stops({
            model: App.models.Stop,
            id: this.get("id")
        });
        stops.fetch();
        this.set({
            stops: stops
        });
        this.set({unique: true});
        this.calculateTotalTime();
    },
    calculateTotalTime: function() {
        this.get("stops").each(function(num) {
            console.log("Model!");
        });
        console.log("Unique: ", this.get("unique"));
    }
});

控制台打印输出为:

Model!
Unique:  true

应该有四个“模型!”,因为模型的数量是四个。

最奇怪的是,一切都在控制台中运行得很好:

window.line.get("stops").each(function(num) {
            console.log("Model!");
        });
Model!
Model!
Model!
Model!

JS 是用 Sprockets 编译的:

//= require ./init

//= require ./lib/jquery
//= require ./lib/underscore
//= require ./lib/backbone
//= require ./lib/raphael

//= require_tree ./controllers
//= require_tree ./models
//= require_tree ./views

//= require ./main

init.js:

window.App = {};
App.views = [];
App.models = [];

main.js:

$(function() {
  window.line = new App.models.Line({name: "4", id: 4});
  window.lineView = new App.views.Line({model: line});
  $("#outer").append(lineView.render().el);
});

一些其他奇怪的行为:

console.log(this.get("stops"))<模型中的 /code> 会产生这个相当正常的对象:

child
  _byCid: Object
  _byId: Object
  _onModelEvent: function () { [native code] }
  _removeReference: function () { [native code] }
  id: 4
  length: 4
  models: Array[4]
    0: Backbone.Model
    1: Backbone.Model
    2: Backbone.Model
    3: Backbone.Model
  length: 4
  __proto__: Array[0]
  __proto__: ctor

但是调用 console.log(this.get("stops").models) 应该会产生数组,但只返回这个,一个数组没有有用属性的单个对象:

[
  Backbone.Model
  _callbacks: Object
  _changed: false
  _changing: false
  _escapedAttributes: Object
  _previousAttributes: Object
  attributes: Object
    id: 4
    model: function (){ return parent.apply(this, arguments); }
    __proto__: Object
    cid: "c1"
    id: 4
  __proto__: Object
]

我怀疑这一切都是由于对 this 本质的一些误解。很高兴提供任何帮助。

I've got a Backbone model line that contains a collection of the model Stop.
At some point, I want to iterate through the stops in the line and get the total travel time along the line, using the Underscore function reduce.

This does not work, however. It seems that something happens with the collection at some point.
It seems to contain only one object without meaningful attributes, although I know for a fact that it has been populated with four stop-models with valid attributes.

The model:

App.models.Line = Backbone.Model.extend({
    initialize: function() {
        var stops = new App.models.Stops({
            model: App.models.Stop,
            id: this.get("id")
        });
        stops.fetch();
        this.set({
            stops: stops
        });
        this.set({unique: true});
        this.calculateTotalTime();
    },
    calculateTotalTime: function() {
        this.get("stops").each(function(num) {
            console.log("Model!");
        });
        console.log("Unique: ", this.get("unique"));
    }
});

Console printout is:

Model!
Unique:  true

There should be four "Model!", since the number of models is four.

The strangest thing is that everything works just fine in the console:

window.line.get("stops").each(function(num) {
            console.log("Model!");
        });
Model!
Model!
Model!
Model!

The JS is compiled with Sprockets:

//= require ./init

//= require ./lib/jquery
//= require ./lib/underscore
//= require ./lib/backbone
//= require ./lib/raphael

//= require_tree ./controllers
//= require_tree ./models
//= require_tree ./views

//= require ./main

init.js:

window.App = {};
App.views = [];
App.models = [];

main.js:

$(function() {
  window.line = new App.models.Line({name: "4", id: 4});
  window.lineView = new App.views.Line({model: line});
  $("#outer").append(lineView.render().el);
});

Some other strange behaviour:

console.log(this.get("stops")) in the model yields this fairly normal object:

child
  _byCid: Object
  _byId: Object
  _onModelEvent: function () { [native code] }
  _removeReference: function () { [native code] }
  id: 4
  length: 4
  models: Array[4]
    0: Backbone.Model
    1: Backbone.Model
    2: Backbone.Model
    3: Backbone.Model
  length: 4
  __proto__: Array[0]
  __proto__: ctor

But calling console.log(this.get("stops").models), which should yield the array, returns only this, an array of a single object with no useful attributes:

[
  Backbone.Model
  _callbacks: Object
  _changed: false
  _changing: false
  _escapedAttributes: Object
  _previousAttributes: Object
  attributes: Object
    id: 4
    model: function (){ return parent.apply(this, arguments); }
    __proto__: Object
    cid: "c1"
    id: 4
  __proto__: Object
]

I suspect this is all down to some misunderstanding about the nature of this. Glad for any help provided.

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

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

发布评论

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

评论(1

羞稚 2024-12-17 13:54:18

stops.fetch() 是一个异步过程,因此您在其之后编写的代码可能会在获取结果从服务器返回之前触发。

您需要修改代码才能在获取返回后运行所有内容。最简单的方法是使用 stops 集合中的 reset 事件:

App.models.Line = Backbone.Model.extend({
    initialize: function() {
        var stops = new App.models.Stops({
            model: App.models.Stop,
            id: this.get("id")
        });


        // store the stops, and then bind to the event
        this.set({stops: stops});
        stops.bind("reset", this.stopsLoaded, this);
        stops.fetch();

    },

    stopsLoaded: function(){
        // get the stops, now that the collection has been populated
        var stops = this.get("stops");
        this.set({unique: true});
        this.calculateTotalTime();
    },

    calculateTotalTime: function() {
        this.get("stops").each(function(num) {
            console.log("Model!");
        });
        console.log("Unique: ", this.get("unique"));
    }
});

它在控制台中工作的原因是因为当您键入代码来评估模型停止时,fetch 调用已返回并填充集合。

希望有帮助

stops.fetch() is an asynchronous process, so the code that you have written right after it will likely fire before the results of the fetch have come back from the server.

you'll need to modify your code to run everything after the fetch comes back. the easiest way to do this is with the reset event from the stops collection:

App.models.Line = Backbone.Model.extend({
    initialize: function() {
        var stops = new App.models.Stops({
            model: App.models.Stop,
            id: this.get("id")
        });


        // store the stops, and then bind to the event
        this.set({stops: stops});
        stops.bind("reset", this.stopsLoaded, this);
        stops.fetch();

    },

    stopsLoaded: function(){
        // get the stops, now that the collection has been populated
        var stops = this.get("stops");
        this.set({unique: true});
        this.calculateTotalTime();
    },

    calculateTotalTime: function() {
        this.get("stops").each(function(num) {
            console.log("Model!");
        });
        console.log("Unique: ", this.get("unique"));
    }
});

the reason it works in your console is because by the time you type out the code to evaluate the model's stops, the fetch call has already returned and populated the collection.

hope that helps

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