Backbone: 集合和模型获取/保存等状态

创建于 2013-01-24  ·  9评论  ·  资料来源: jashkenas/backbone

为了能够知道集合是否已填充,或正在填充,可能有类似


collection.fetch();
collection.isFetching()===true; // display loading 

(collection.isFetching()===false; && collection.length) // display no records found

真实用例(简化,对象在系统深处传递):

javascript() // somewhere in the code collection = new MyCollection(); // somewhere else in the code view = new MyView({collection:collection}); // and somewhere else in the code collection.fetch();

视图侦听收集信号,并显示加载/无记录/记录列表

对于模型,甚至可能有保存/删除/更新的东西

question

最有用的评论

@braddunbar@caseywebdev的想法是将这两部分解耦。 (view应该可以在任何状态下获取collection,而不仅仅是_'clean'_collection)
我知道我可以使用信号来做到这一点,但在许多情况下,这不能通过这种方式做到。 行动的顺序很重要

我同意 view 应该监听 'request' 和 'sync' 信号,但请求信号可能在集合传递给 view 之前发送,因此 view 不知道集合正在获取。

考虑一个示例,您的视图获取任意集合。 该集合在传递到视图时可以是 _fetched_ 、 _fetching_ 或 _unfetched_ (tl:dr 参见示例 3)

示例 1(信号将起作用的地方)

collection = new Backbone.Collection();
view = new Backbone.View({collection:collection});
view.render();
// what should the view render ?
collection.fetch() // now sync signal gets sent

示例 2(视图已获取,但 emty 集合,信号也将起作用)

collection = new Backbone.Collection();
collection.fetch();  // now sync signal gets sent
// after fetch completes
// view won't be able to receive 'sync' signal
view = new Backbone.View({collection:collection}); 
view.render(); 
// at this point collection.length == 0. 
// I guess the view can listen to 'sync' and then render 'empty' 

示例 3(最重要的是,信号不起作用)

collection = new Backbone.Collection();
collection.fetch();  // now 'request' signal gets sent, but it is pending
// view won't be able to receive 'request' signal
view = new Backbone.View({collection:collection}); // at this point collection.length == 0
// view did not receive the 'request' signal, therefore has no idea that the collection is fetching
// and the view should render  'loading'
// after 2 seconds, 'sync' signal gets sent

视图不应该假设如果 collection.length == 0 那么它是未获取的。
视图也不应该假设它在未获取状态(或任何其他状态)下被赋予集合。

如果我们想将集合与视图解耦,那么视图必须能够知道集合状态是什么。

模型也是如此

所有9条评论

嗨@g00fy-! 为此,我建议您使用"request""sync"事件。 你怎么认为?

collection.on('request', function() {
  // loading...
}).on('sync', function() {
  // display records or "none found"
});
collection.fetch();

_Edit - 我的意思是"request"事件,而不是"fetch" ._

我认为这是一个很好的主意@braddunbar!

谢谢@caseywebdev! :)

如果这对您不起作用,请告诉我们@g00fy-。

@braddunbar@caseywebdev的想法是将这两部分解耦。 (view应该可以在任何状态下获取collection,而不仅仅是_'clean'_collection)
我知道我可以使用信号来做到这一点,但在许多情况下,这不能通过这种方式做到。 行动的顺序很重要

我同意 view 应该监听 'request' 和 'sync' 信号,但请求信号可能在集合传递给 view 之前发送,因此 view 不知道集合正在获取。

考虑一个示例,您的视图获取任意集合。 该集合在传递到视图时可以是 _fetched_ 、 _fetching_ 或 _unfetched_ (tl:dr 参见示例 3)

示例 1(信号将起作用的地方)

collection = new Backbone.Collection();
view = new Backbone.View({collection:collection});
view.render();
// what should the view render ?
collection.fetch() // now sync signal gets sent

示例 2(视图已获取,但 emty 集合,信号也将起作用)

collection = new Backbone.Collection();
collection.fetch();  // now sync signal gets sent
// after fetch completes
// view won't be able to receive 'sync' signal
view = new Backbone.View({collection:collection}); 
view.render(); 
// at this point collection.length == 0. 
// I guess the view can listen to 'sync' and then render 'empty' 

示例 3(最重要的是,信号不起作用)

collection = new Backbone.Collection();
collection.fetch();  // now 'request' signal gets sent, but it is pending
// view won't be able to receive 'request' signal
view = new Backbone.View({collection:collection}); // at this point collection.length == 0
// view did not receive the 'request' signal, therefore has no idea that the collection is fetching
// and the view should render  'loading'
// after 2 seconds, 'sync' signal gets sent

视图不应该假设如果 collection.length == 0 那么它是未获取的。
视图也不应该假设它在未获取状态(或任何其他状态)下被赋予集合。

如果我们想将集合与视图解耦,那么视图必须能够知道集合状态是什么。

模型也是如此

@g00fy如果您不能在将集合发送到视图后仅fetch集合,请在您的集合上设置fetching标志等。

collection.on({
  request: function () { this.fetching = true; },
  'sync error': function () { this.fetching = false; }
});

现在您的视图可以访问this.collection.fetching并等待this.collection触发syncerror事件。

@caseywebdev
请求可能会中止,或者可能同时发送两个请求。

// example 1
collection.fetch().abort()  // and collection.fetching == true
// example 2 - don't care about abort();
collection.fetch();
collection.fetch();
// 1st request compleated
!!collection.fetching == false // but the 2nd request is pending - should it be loading or not?
// 2nd request completed

解决这个问题的方法是连接 do deferred xhr

collection.on({
    'request':function(model,xhr){ 
        this.fetching = true; 
        xhr.fail(function(){this.fetching = false }.bind(this));
    },
    'sync error': function () { this.fetching = false; }
});

这就是为什么,我认为将其内置可能很方便,但另一方面,如果像这样的每个增强都通过,BB 代码库将变得臃肿。

如果像这样的每一个增强都通过,BB 代码库就会变得臃肿。

我认为这与腹胀有关,而与方法有关。 您可能希望以多种不同的方式处理并发请求。 Backbone 为您提供处理它们所需的原语,然后让路。

@g00fy-您可能想考虑为您的目的编写一个有限状态机Chaplin.js 有一个应该很容易复制的,还有ifandelse/machina.js (请参阅博客文章)可能适合您的特定用例。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

miguelpayet picture miguelpayet  ·  9评论

PavelKoroteev picture PavelKoroteev  ·  10评论

rubiii picture rubiii  ·  12评论

jonathan picture jonathan  ·  11评论

rafde picture rafde  ·  9评论