Skip to content

Commit f42bb6e

Browse files
committed
Indexer.
1 parent fbc013b commit f42bb6e

File tree

4 files changed

+73
-1
lines changed

4 files changed

+73
-1
lines changed

src/indexer.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
;(function(Model) {
2+
Model.Indexer = function(collection, attribute) {
3+
this.collection = collection
4+
this.attribute = attribute
5+
this.index = {}
6+
this.collection.on("add", this.add, this)
7+
this.collection.on("remove", this.remove, this)
8+
this.collection.forEach(this.add, this)
9+
}
10+
11+
Model.Indexer.prototype.add = function(model) {
12+
this.get(model.get(this.attribute)).add(model)
13+
model.on("change:" + this.attribute, this.change, this)
14+
}
15+
16+
Model.Indexer.prototype.change = function(model, from, to) {
17+
this.get(from).remove(model)
18+
this.get(to).add(model)
19+
}
20+
21+
Model.Indexer.prototype.get = function(key) {
22+
return this.index[key] || (this.index[key] = new Model.Collection())
23+
}
24+
25+
Model.Indexer.prototype.remove = function(model) {
26+
this.get(model.get(this.attribute)).remove(model)
27+
model.off("change:" + this.attribute, this.change, this)
28+
}
29+
})(Model);

src/model_model.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
}
1919

2020
function set(name, value) {
21+
var from = this.get(name)
22+
2123
// Don't write to attributes yet, store in changes for now.
2224
if (this.attributes[name] === value) {
2325
// Clean up any stale changes.
@@ -26,7 +28,7 @@
2628
this.changes[name] = value
2729
}
2830

29-
this.emit("change:" + name, this)
31+
this.emit("change:" + name, this, from, value)
3032
}
3133

3234
Model.Model.prototype = {

test/index.html

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
<script src="../src/model_rest.js"></script>
2626
<script src="../src/model_uid.js"></script>
2727
<script src="../src/model_version.js"></script>
28+
<script src="../src/indexer.js"></script>
2829

2930
<!-- Helpers -->
3031
<script src="javascripts/helpers.js"></script>
@@ -41,6 +42,7 @@
4142
<script src="tests/model_local_storage_test.js"></script>
4243
<script src="tests/inheritance_test.js"></script>
4344
<script src="tests/plugin_test.js"></script>
45+
<script src="tests/indexer_test.js"></script>
4446
</head>
4547
<body>
4648
<h1 id="qunit-header">js-model Tests</h1>

test/tests/indexer_test.js

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
module("Model.Indexer")
2+
3+
test("manages its index correctly", function() {
4+
var Story = Model("story")
5+
6+
var story1 = new Story({ project_id: 1 })
7+
var story2 = new Story({ project_id: 2 })
8+
var story3 = new Story({ project_id: 3 })
9+
10+
Story.collection.push(story1, story2, story3)
11+
12+
var index = new Model.Indexer(Story.collection, "project_id")
13+
14+
ok(index.get(1).first() === story1, "index is populated")
15+
ok(index.get(2).first() === story2, "index is populated")
16+
ok(index.get(3).first() === story3, "index is populated")
17+
18+
var story4 = new Story({ project_id: 4 })
19+
20+
equal(index.get(4).length, 0, "empty keys respond to the same interface")
21+
22+
Story.collection.add(story4)
23+
24+
equal(index.get(4).length, 1, "index includes models added to the collection")
25+
26+
story4.set("project_id", 1)
27+
28+
equal(index.get(1).length, 2, "index is kept up to date with updated models")
29+
ok(index.get(1).first() === story1)
30+
ok(index.get(1).last() === story4)
31+
equal(index.get(4).length, 0)
32+
33+
equal(story2._events["change:project_id"].length, 1, "just checking")
34+
35+
Story.collection.remove(story2)
36+
37+
equal(index.get(2).length, 0, "model is removed from the index")
38+
equal(story2._events["change:project_id"].length, 0, "Indexer callbacks are cleaned up")
39+
})

0 commit comments

Comments
 (0)