Load incomplete records when trying to get unknown attribute
In order to minimize ajax requests, I implemented isComplete property, which can be used to check if record is fetched from the API or if it was just partially loaded (for example by pusher event). This is nice in terms of requests reduction, but caries risk of showing incomplete data. This commit fixes this situation by saving which attributes were provided on "incomplete" load and triggering refresh when any unknown attribute is tried to be fetched. The implementation is really simple and will probably need refactoring, but I would like to test it in the wild before putting much more time into it.
This commit is contained in:
parent
393ef62eae
commit
c05ce673bf
|
@ -23,7 +23,7 @@ input assets.scripts do
|
|||
safe_concat assets.vendor_order, 'vendor.js'
|
||||
end
|
||||
|
||||
match 'spec/*.js' do
|
||||
match '{spec,spec/unit}/*.js' do
|
||||
concat 'spec/specs.js'
|
||||
end
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ GIT
|
|||
|
||||
GIT
|
||||
remote: git://github.com/travis-ci/travis-api.git
|
||||
revision: 816ebc66c8b65c44d6144e721b1b4f048e86d7df
|
||||
revision: 558847f6555202adb7da4f7d31a7b2b80ab4bac2
|
||||
specs:
|
||||
travis-api (0.0.1)
|
||||
backports (~> 2.5)
|
||||
|
@ -61,7 +61,7 @@ GIT
|
|||
|
||||
GIT
|
||||
remote: git://github.com/travis-ci/travis-core.git
|
||||
revision: 56ca16046cba99cc0b4cd0c520c6bb13ace9932a
|
||||
revision: abac97114a36f3a6715e118cc1f90c05a08004f6
|
||||
branch: sf-travis-api
|
||||
specs:
|
||||
travis-core (0.0.1)
|
||||
|
|
|
@ -76,18 +76,21 @@ Travis.Store = DS.Store.extend
|
|||
# if we need sideload becasue we have side records with other events it needs to
|
||||
# be revised
|
||||
if type == Travis.Build && json.repository
|
||||
result = @_loadIncomplete(Travis.Repo, 'repository', json.repository)
|
||||
@_loadIncomplete(type, root, json[root])
|
||||
result = @loadIncomplete(Travis.Repo, json.repository)
|
||||
@loadIncomplete(type, json[root])
|
||||
|
||||
_loadIncomplete: (type, root, hash) ->
|
||||
loadIncomplete: (type, hash) ->
|
||||
result = @merge(type, hash)
|
||||
|
||||
if result && result.clientId
|
||||
record = @findByClientId(type, result.clientId)
|
||||
unless record.get('complete')
|
||||
record.set 'incomplete', true
|
||||
record.loadedAttributes = Object.keys hash
|
||||
|
||||
@_updateAssociations(type, root, hash)
|
||||
@_updateAssociations(type, type.singularName(), hash)
|
||||
|
||||
record
|
||||
|
||||
_loadMany: (store, type, json) ->
|
||||
root = type.pluralName()
|
||||
|
|
|
@ -2,6 +2,12 @@
|
|||
primaryKey: 'id'
|
||||
id: DS.attr('number')
|
||||
|
||||
get: (name) ->
|
||||
if @constructor.isAttribute(name) && @get('incomplete') && !@isAttributeLoaded(name)
|
||||
@loadTheRest()
|
||||
|
||||
@_super.apply this, arguments
|
||||
|
||||
refresh: ->
|
||||
if id = @get('id')
|
||||
store = @get('store')
|
||||
|
@ -12,6 +18,9 @@
|
|||
@set(key, value) unless key is 'id'
|
||||
this
|
||||
|
||||
isAttributeLoaded: (name) ->
|
||||
@loadedAttributes.contains(name)
|
||||
|
||||
isComplete: (->
|
||||
if @get 'incomplete'
|
||||
@loadTheRest()
|
||||
|
@ -63,3 +72,16 @@
|
|||
pluralName: ->
|
||||
Travis.app.store.adapter.pluralize(@singularName())
|
||||
|
||||
isAttribute: (name) ->
|
||||
unless @attributesSaved
|
||||
@_saveAttributes()
|
||||
@cachedAttributes.contains(name)
|
||||
|
||||
_saveAttributes: ->
|
||||
@attributesSaved = true
|
||||
|
||||
cachedAttributes = []
|
||||
@eachComputedProperty (name, meta) ->
|
||||
cachedAttributes.pushObject name if meta.isAttribute
|
||||
|
||||
@cachedAttributes = cachedAttributes
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -8865,3 +8865,73 @@ return sinon;}.call(typeof window != 'undefined' && window || {}));
|
|||
this.Date.UTC = _Date.UTC;
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var record, store;
|
||||
|
||||
Travis.Foo = Travis.Model.extend({
|
||||
name: DS.attr('string'),
|
||||
description: DS.attr('string')
|
||||
});
|
||||
|
||||
record = null;
|
||||
|
||||
store = null;
|
||||
|
||||
$.mockjax({
|
||||
url: '/foos/1',
|
||||
responseTime: 10,
|
||||
responseText: {
|
||||
foo: {
|
||||
id: 1,
|
||||
name: 'foo',
|
||||
description: 'bar'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Travis.Model', function() {
|
||||
return describe('with incomplete record', function() {
|
||||
beforeEach(function() {
|
||||
var attrs;
|
||||
store = Travis.Store.create();
|
||||
attrs = {
|
||||
id: 1,
|
||||
name: 'foo'
|
||||
};
|
||||
return record = store.loadIncomplete(Travis.Foo, attrs);
|
||||
});
|
||||
it('shows if attribute is loaded', function() {
|
||||
expect(record.isAttributeLoaded('name')).toBeTruthy();
|
||||
return expect(record.isAttributeLoaded('description')).toBeFalsy();
|
||||
});
|
||||
it('does not trigger a request when getting known attribute', function() {
|
||||
expect(record.get('name')).toEqual('foo');
|
||||
waits(50);
|
||||
return runs(function() {
|
||||
return expect(record.get('complete')).toBeFalsy();
|
||||
});
|
||||
});
|
||||
it('loads missing data on try to get it', function() {
|
||||
expect(record.get('name')).toEqual('foo');
|
||||
expect(record.get('description')).toBeNull();
|
||||
waits(50);
|
||||
return runs(function() {
|
||||
expect(record.get('description')).toEqual('bar');
|
||||
expect(record.get('complete')).toBeTruthy();
|
||||
return expect(record.get('isComplete')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
return it('does not set incomplete on the record twice', function() {
|
||||
record.get('description');
|
||||
waits(50);
|
||||
return runs(function() {
|
||||
store.loadIncomplete(Travis.Foo, {
|
||||
id: 1
|
||||
});
|
||||
return expect(record.get('incomplete')).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}).call(this);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1 +1 @@
|
|||
4b27d9a7
|
||||
e090359a
|
Loading…
Reference in New Issue
Block a user