Skip to content

Commit 384f0ae

Browse files
vicbvsavkin
authored andcommitted
feat(Change Detection): Child watch groups
1 parent 7482b68 commit 384f0ae

File tree

2 files changed

+126
-5
lines changed

2 files changed

+126
-5
lines changed

modules/change_detection/src/watch_group.js

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ export class ProtoWatchGroup {
5050
if (this.headRecord !== null) {
5151
this._createRecords(watchGroup, formatters);
5252
this._setDestination();
53-
5453
}
5554
return watchGroup;
5655
}
@@ -88,6 +87,11 @@ export class WatchGroup {
8887
this.headEnabledRecord = null;
8988
this.tailEnabledRecord = null;
9089
this.context = null;
90+
91+
this.childHead = null;
92+
this.childTail = null;
93+
this.next = null;
94+
this.prev = null;
9195
}
9296

9397
addRecord(record:Record) {
@@ -149,12 +153,35 @@ export class WatchGroup {
149153
}
150154
}
151155

152-
insertChildGroup(newChild:WatchGroup, insertAfter:WatchGroup) {
153-
throw 'not implemented';
156+
addChild(child:WatchGroup) {
157+
if (isBlank(this.childTail)) {
158+
this.childHead = this.childTail = child;
159+
this._attachRecordsFromWatchGroup(child);
160+
161+
} else {
162+
this.childTail.next = child;
163+
child.prev = this.childTail;
164+
this.childTail = child;
165+
this._attachRecordsFromWatchGroup(child);
166+
}
154167
}
155168

156-
remove() {
157-
throw 'not implemented';
169+
_attachRecordsFromWatchGroup(child:WatchGroup) {
170+
if (isPresent(this.tailRecord)) {
171+
if (isPresent(child.headRecord)) {
172+
this.tailRecord.next = child.headRecord;
173+
this.tailRecord.nextEnabled = child.headRecord;
174+
175+
child.headRecord.prev = this.tailRecord;
176+
child.headRecord.prevEnabled = this.tailRecord;
177+
}
178+
} else {
179+
this.headRecord = child.headRecord;
180+
this.headEnabledRecord = child.headEnabledRecord;
181+
}
182+
183+
this.tailRecord = child.tailRecord;
184+
this.tailEnabledRecord = child.tailEnabledRecord;
158185
}
159186

160187
/**
@@ -172,6 +199,14 @@ export class WatchGroup {
172199
record.updateContext(context);
173200
}
174201
}
202+
203+
get _tailRecordIncludingChildren():Record {
204+
var lastGroup = this;
205+
while (lastGroup.childTail !== null) {
206+
lastGroup = lastGroup.childTail;
207+
}
208+
return lastGroup.tailRecord;
209+
}
175210
}
176211

177212
export class WatchGroupDispatcher {

modules/change_detection/test/watch_group_spec.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,92 @@ export function main() {
5353
});
5454
});
5555

56+
describe("adding children", () => {
57+
it("should add child watch group", () => {
58+
var parent = new WatchGroup(null, null);
59+
var child1 = new WatchGroup(null, null);
60+
var child2 = new WatchGroup(null, null);
61+
parent.addChild(child1);
62+
parent.addChild(child2);
63+
64+
expect(parent.childHead).toBe(child1);
65+
expect(parent.childTail).toBe(child2);
66+
67+
expect(child1.next).toBe(child2);
68+
expect(child2.prev).toBe(child1);
69+
});
70+
71+
it("should link all records", () => {
72+
var parent = new WatchGroup(null, null);
73+
var parentRecord = createRecord(parent);
74+
parent.addRecord(parentRecord);
75+
76+
var child = new WatchGroup(null, null);
77+
var childRecord = createRecord(child);
78+
child.addRecord(childRecord);
79+
80+
parent.addChild(child);
81+
82+
expect(parent.headRecord).toBe(parentRecord);
83+
expect(parent.tailRecord).toBe(childRecord);
84+
85+
expect(parent.headEnabledRecord).toBe(parentRecord);
86+
expect(parent.tailEnabledRecord).toBe(childRecord);
87+
88+
expect(parentRecord.next).toBe(childRecord);
89+
expect(childRecord.prev).toBe(parentRecord);
90+
});
91+
92+
it("should work when parent has no records", () => {
93+
var parent = new WatchGroup(null, null);
94+
95+
var child = new WatchGroup(null, null);
96+
var childRecord = createRecord(child);
97+
child.addRecord(childRecord);
98+
99+
parent.addChild(child);
100+
101+
expect(parent.headRecord).toBe(childRecord);
102+
expect(parent.tailRecord).toBe(childRecord);
103+
104+
expect(parent.headEnabledRecord).toBe(childRecord);
105+
expect(parent.tailEnabledRecord).toBe(childRecord);
106+
});
107+
108+
it("should work when parent has no records and first child has no records", () => {
109+
var parent = new WatchGroup(null, null);
110+
var firstChild = new WatchGroup(null, null);
111+
parent.addChild(firstChild);
112+
113+
var child = new WatchGroup(null, null);
114+
var childRecord = createRecord(child);
115+
child.addRecord(childRecord);
116+
117+
parent.addChild(child);
118+
119+
expect(parent.headRecord).toBe(childRecord);
120+
expect(parent.tailRecord).toBe(childRecord);
121+
122+
expect(parent.headEnabledRecord).toBe(childRecord);
123+
expect(parent.tailEnabledRecord).toBe(childRecord);
124+
});
125+
126+
it("should work when second child has no records", () => {
127+
var parent = new WatchGroup(null, null);
128+
129+
var firstChild = new WatchGroup(null, null);
130+
var childRecord = createRecord(firstChild);
131+
firstChild.addRecord(childRecord);
132+
parent.addChild(firstChild);
133+
134+
var secondChild = new WatchGroup(null, null);
135+
parent.addChild(secondChild);
136+
137+
expect(parent.childHead).toBe(firstChild);
138+
expect(parent.childTail).toBe(secondChild);
139+
});
140+
});
141+
56142
describe("enabling/disabling records", () => {
57143
it("should disable a single record", () => {
58144
var wg = new WatchGroup(null, null);

0 commit comments

Comments
 (0)