Skip to content

Commit ba78164

Browse files
committed
1 parent f969ea0 commit ba78164

File tree

9 files changed

+315
-333
lines changed

9 files changed

+315
-333
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111

1212
###### Backwards compatible bug fixes
1313
- #135 - loadrelations loop
14+
- #140 - lastModified changes when loading distant related objects
15+
16+
###### Other
17+
- #138 - Performance optimizations
18+
- #139 - Documentation error
1419

1520
##### 1.0.0-beta.1 - 23 August 2014
1621

dist/angular-data.js

+163-170
Large diffs are not rendered by default.

dist/angular-data.min.js

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@
3636
"karma-script-launcher": "^0.1.0",
3737
"karma-firefox-launcher": "^0.1.3",
3838
"karma-phantomjs-launcher": "^0.1.4",
39-
"karma-mocha": "^0.1.8",
39+
"karma-mocha": "^0.1.9",
4040
"karma-sinon": "^1.0.3",
4141
"karma-spec-reporter": "^0.0.13",
42-
"time-grunt": "^0.4.0",
42+
"time-grunt": "^1.0.0",
4343
"jit-grunt": "^0.8.0",
4444
"grunt-docular": "^0.1.4"
4545
},

src/datastore/async_methods/loadRelations.js

+22-29
Original file line numberDiff line numberDiff line change
@@ -95,37 +95,30 @@ function loadRelations(resourceName, instance, relations, options) {
9595
var tasks = [];
9696
var fields = [];
9797

98-
DS.utils.forOwn(definition.relations, function (relatedModels, type) {
99-
DS.utils.forOwn(relatedModels, function (defs, relationName) {
100-
if (!DS.utils.isArray(defs)) {
101-
defs = [defs];
98+
DS.utils.forEach(definition.relationList, function (def) {
99+
var relationName = def.relation;
100+
if (DS.utils.contains(relations, relationName)) {
101+
var task;
102+
var params = {};
103+
params[def.foreignKey] = instance[definition.idAttribute];
104+
105+
if (def.type === 'hasMany') {
106+
task = DS.findAll(relationName, params, options);
107+
} else if (def.type === 'hasOne') {
108+
if (def.localKey && instance[def.localKey]) {
109+
task = DS.find(relationName, instance[def.localKey], options);
110+
} else if (def.foreignKey) {
111+
task = DS.findAll(relationName, params, options);
112+
}
113+
} else {
114+
task = DS.find(relationName, instance[def.localKey], options);
102115
}
103116

104-
defs.forEach(function (def) {
105-
if (DS.utils.contains(relations, relationName)) {
106-
var task;
107-
var params = {};
108-
params[def.foreignKey] = instance[definition.idAttribute];
109-
110-
if (type === 'hasMany') {
111-
task = DS.findAll(relationName, params, options);
112-
} else if (type === 'hasOne') {
113-
if (def.localKey && instance[def.localKey]) {
114-
task = DS.find(relationName, instance[def.localKey], options);
115-
} else if (def.foreignKey) {
116-
task = DS.findAll(relationName, params, options);
117-
}
118-
} else {
119-
task = DS.find(relationName, instance[def.localKey], options);
120-
}
121-
122-
if (task) {
123-
tasks.push(task);
124-
fields.push(def.localField);
125-
}
126-
}
127-
});
128-
});
117+
if (task) {
118+
tasks.push(task);
119+
fields.push(def.localField);
120+
}
121+
}
129122
});
130123

131124
promise = promise

src/datastore/sync_methods/defineResource.js

+26-9
Original file line numberDiff line numberDiff line change
@@ -133,18 +133,35 @@ function defineResource(definition) {
133133
var def = definitions[definition.name];
134134

135135
// Setup nested parent configuration
136-
if (def.relations && def.relations.belongsTo) {
137-
DS.utils.forOwn(def.relations.belongsTo, function (relatedModel, modelName) {
138-
if (!DS.utils.isArray(relatedModel)) {
139-
relatedModel = [relatedModel];
140-
}
141-
DS.utils.forEach(relatedModel, function (relation) {
142-
if (relation.parent) {
143-
def.parent = modelName;
144-
def.parentKey = relation.localKey;
136+
if (def.relations) {
137+
def.relationList = [];
138+
def.relationFields = [];
139+
DS.utils.forOwn(def.relations, function (relatedModels, type) {
140+
DS.utils.forOwn(relatedModels, function (defs, relationName) {
141+
if (!DS.utils.isArray(defs)) {
142+
relatedModels[relationName] = [defs];
145143
}
144+
DS.utils.forEach(relatedModels[relationName], function (d) {
145+
d.type = type;
146+
d.relation = relationName;
147+
d.name = def.name;
148+
def.relationList.push(d);
149+
def.relationFields.push(d.localField);
150+
});
146151
});
147152
});
153+
if (def.relations.belongsTo) {
154+
DS.utils.forOwn(def.relations.belongsTo, function (relatedModel, modelName) {
155+
DS.utils.forEach(relatedModel, function (relation) {
156+
if (relation.parent) {
157+
def.parent = modelName;
158+
def.parentKey = relation.localKey;
159+
}
160+
});
161+
});
162+
}
163+
DS.utils.deepFreeze(def.relations);
164+
DS.utils.deepFreeze(def.relationList);
148165
}
149166

150167
def.getEndpoint = function (attrs, options) {

src/datastore/sync_methods/inject.js

+50-62
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,21 @@ function _inject(definition, resource, attrs) {
1313
var DS = this;
1414
var $log = DS.$log;
1515

16-
function _react(added, removed, changed, oldValueFn) {
16+
function _react(added, removed, changed, oldValueFn, firstTime) {
1717
var target = this;
1818
var item;
1919
var innerId = (oldValueFn && oldValueFn(definition.idAttribute)) ? oldValueFn(definition.idAttribute) : target[definition.idAttribute];
2020

21-
resource.modified[innerId] = DS.utils.updateTimestamp(resource.modified[innerId]);
22-
resource.collectionModified = DS.utils.updateTimestamp(resource.collectionModified);
21+
DS.utils.forEach(definition.relationFields, function (field) {
22+
delete added[field];
23+
delete removed[field];
24+
delete changed[field];
25+
});
26+
27+
if (!DS.utils.isEmpty(added) || !DS.utils.isEmpty(removed) || !DS.utils.isEmpty(changed) || firstTime) {
28+
resource.modified[innerId] = DS.utils.updateTimestamp(resource.modified[innerId]);
29+
resource.collectionModified = DS.utils.updateTimestamp(resource.collectionModified);
30+
}
2331

2432
if (definition.computed) {
2533
item = DS.get(definition.name, innerId);
@@ -40,17 +48,10 @@ function _inject(definition, resource, attrs) {
4048

4149
if (definition.relations) {
4250
item = DS.get(definition.name, innerId);
43-
DS.utils.forOwn(definition.relations, function (relatedModels) {
44-
DS.utils.forOwn(relatedModels, function (defs, relationName) {
45-
if (!DS.utils.isArray(defs)) {
46-
defs = [defs];
47-
}
48-
defs.forEach(function (def) {
49-
if (item[def.localField] && (def.localKey in added || def.localKey in removed || def.localKey in changed)) {
50-
DS.link(definition.name, item[definition.idAttribute], [relationName]);
51-
}
52-
});
53-
});
51+
DS.utils.forEach(definition.relationList, function (def) {
52+
if (item[def.localField] && (def.localKey in added || def.localKey in removed || def.localKey in changed)) {
53+
DS.link(definition.name, item[definition.idAttribute], [def.relation]);
54+
}
5455
});
5556
}
5657

@@ -109,7 +110,7 @@ function _inject(definition, resource, attrs) {
109110
resource.observers[id].open(_react, item);
110111
resource.index.put(id, item);
111112

112-
_react.call(item, {}, {}, {});
113+
_react.call(item, {}, {}, {}, null, true);
113114
} else {
114115
DS.utils.deepMixIn(item, attrs);
115116
if (typeof resource.index.touch === 'function') {
@@ -133,57 +134,43 @@ function _inject(definition, resource, attrs) {
133134

134135
function _injectRelations(definition, injected, options) {
135136
var DS = this;
136-
DS.utils.forOwn(definition.relations, function (relatedModels, type) {
137-
DS.utils.forOwn(relatedModels, function (defs, relationName) {
138-
if (!DS.utils.isArray(defs)) {
139-
defs = [defs];
140-
}
141137

142-
function _process(def, injected) {
143-
if (DS.definitions[relationName] && injected[def.localField] && !data.injectedSoFar[relationName + injected[def.localField][DS.definitions[relationName].idAttribute]]) {
144-
try {
145-
data.injectedSoFar[relationName + injected[def.localField][DS.definitions[relationName].idAttribute]] = 1;
146-
injected[def.localField] = DS.inject(relationName, injected[def.localField], options);
147-
} catch (err) {
148-
DS.$log.error(errorPrefix(definition.name) + 'Failed to inject ' + type + ' relation: "' + relationName + '"!', err);
149-
}
150-
} else if (options.findBelongsTo && type === 'belongsTo') {
151-
if (DS.utils.isArray(injected)) {
152-
DS.utils.forEach(injected, function (injectedItem) {
153-
DS.link(definition.name, injectedItem[definition.idAttribute], [relationName]);
154-
});
155-
} else {
156-
DS.link(definition.name, injected[definition.idAttribute], [relationName]);
157-
}
158-
} else if (options.findHasMany && type === 'hasMany') {
159-
if (DS.utils.isArray(injected)) {
160-
DS.utils.forEach(injected, function (injectedItem) {
161-
DS.link(definition.name, injectedItem[definition.idAttribute], [relationName]);
162-
});
163-
} else {
164-
DS.link(definition.name, injected[definition.idAttribute], [relationName]);
165-
}
166-
} else if (options.findHasOne && type === 'hasOne') {
167-
if (DS.utils.isArray(injected)) {
168-
DS.utils.forEach(injected, function (injectedItem) {
169-
DS.link(definition.name, injectedItem[definition.idAttribute], [relationName]);
170-
});
171-
} else {
172-
DS.link(definition.name, injected[definition.idAttribute], [relationName]);
173-
}
174-
}
138+
function _process(def, relationName, injected) {
139+
var relationDef = DS.definitions[relationName];
140+
if (relationDef && injected[def.localField] && !data.injectedSoFar[relationName + injected[def.localField][relationDef.idAttribute]]) {
141+
try {
142+
data.injectedSoFar[relationName + injected[def.localField][relationDef.idAttribute]] = 1;
143+
injected[def.localField] = DS.inject(relationName, injected[def.localField], options);
144+
} catch (err) {
145+
DS.$log.error(errorPrefix(definition.name) + 'Failed to inject ' + def.type + ' relation: "' + relationName + '"!', err);
146+
}
147+
} else if (options.findBelongsTo && def.type === 'belongsTo') {
148+
if (DS.utils.isArray(injected)) {
149+
DS.utils.forEach(injected, function (injectedItem) {
150+
DS.link(definition.name, injectedItem[definition.idAttribute], [relationName]);
151+
});
152+
} else {
153+
DS.link(definition.name, injected[definition.idAttribute], [relationName]);
154+
}
155+
} else if ((options.findHasMany && def.type === 'hasMany') || (options.findHasOne && def.type === 'hasOne')) {
156+
if (DS.utils.isArray(injected)) {
157+
DS.utils.forEach(injected, function (injectedItem) {
158+
DS.link(definition.name, injectedItem[definition.idAttribute], [relationName]);
159+
});
160+
} else {
161+
DS.link(definition.name, injected[definition.idAttribute], [relationName]);
175162
}
163+
}
164+
}
176165

177-
defs.forEach(function (def) {
178-
if (DS.utils.isArray(injected)) {
179-
DS.utils.forEach(injected, function (injectedI) {
180-
_process(def, injectedI);
181-
});
182-
} else {
183-
_process(def, injected);
184-
}
166+
DS.utils.forEach(definition.relationList, function (def) {
167+
if (DS.utils.isArray(injected)) {
168+
DS.utils.forEach(injected, function (injectedI) {
169+
_process(def, def.relation, injectedI);
185170
});
186-
});
171+
} else {
172+
_process(def, def.relation, injected);
173+
}
187174
});
188175
}
189176

@@ -236,6 +223,7 @@ function _injectRelations(definition, injected, options) {
236223
*
237224
* - `{boolean=}` - `findBelongsTo` - Find and attach any existing "belongsTo" relationships to the newly injected item. Potentially expensive if enabled. Default: `false`.
238225
* - `{boolean=}` - `findHasMany` - Find and attach any existing "hasMany" relationships to the newly injected item. Potentially expensive if enabled. Default: `false`.
226+
* - `{boolean=}` - `findHasOne` - Find and attach any existing "hasOne" relationships to the newly injected item. Potentially expensive if enabled. Default: `false`.
239227
* - `{boolean=}` - `linkInverse` - Look in the data store for relations of the injected item(s) and update their links to the injected. Potentially expensive if enabled. Default: `false`.
240228
*
241229
* @returns {object|array} A reference to the item that was injected into the data store or an array of references to

src/datastore/sync_methods/link.js

+19-26
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,27 @@ function errorPrefix(resourceName) {
44

55
function _link(definition, linked, relations) {
66
var DS = this;
7-
DS.utils.forOwn(definition.relations, function (relatedModels, type) {
8-
DS.utils.forOwn(relatedModels, function (defs, relationName) {
9-
if (relations.length && !DS.utils.contains(relations, relationName)) {
10-
return;
7+
DS.utils.forEach(definition.relationList, function (def) {
8+
var relationName = def.relation;
9+
if (relations.length && !DS.utils.contains(relations, relationName)) {
10+
return;
11+
}
12+
var params = {};
13+
if (def.type === 'belongsTo') {
14+
var parent = linked[def.localKey] ? DS.get(relationName, linked[def.localKey]) : null;
15+
if (parent) {
16+
linked[def.localField] = parent;
1117
}
12-
if (!DS.utils.isArray(defs)) {
13-
defs = [defs];
18+
} else if (def.type === 'hasMany') {
19+
params[def.foreignKey] = linked[definition.idAttribute];
20+
linked[def.localField] = DS.defaults.constructor.prototype.defaultFilter.call(DS, DS.store[relationName].collection, relationName, params, { allowSimpleWhere: true });
21+
} else if (def.type === 'hasOne') {
22+
params[def.foreignKey] = linked[definition.idAttribute];
23+
var children = DS.defaults.constructor.prototype.defaultFilter.call(DS, DS.store[relationName].collection, relationName, params, { allowSimpleWhere: true });
24+
if (children.length) {
25+
linked[def.localField] = children[0];
1426
}
15-
16-
defs.forEach(function (def) {
17-
var params = {};
18-
if (type === 'belongsTo') {
19-
var parent = linked[def.localKey] ? DS.get(relationName, linked[def.localKey]) : null;
20-
if (parent) {
21-
linked[def.localField] = parent;
22-
}
23-
} else if (type === 'hasMany') {
24-
params[def.foreignKey] = linked[definition.idAttribute];
25-
linked[def.localField] = DS.defaults.constructor.prototype.defaultFilter.call(DS, DS.store[relationName].collection, relationName, params, { allowSimpleWhere: true });
26-
} else if (type === 'hasOne') {
27-
params[def.foreignKey] = linked[definition.idAttribute];
28-
var children = DS.defaults.constructor.prototype.defaultFilter.call(DS, DS.store[relationName].collection, relationName, params, { allowSimpleWhere: true });
29-
if (children.length) {
30-
linked[def.localField] = children[0];
31-
}
32-
}
33-
});
34-
});
27+
}
3528
});
3629
}
3730

0 commit comments

Comments
 (0)