Skip to content

Commit 7f31036

Browse files
committed
fix(change_detection): pass the correct previous value when using pipes
Closes angular#588
1 parent 1d4ffd9 commit 7f31036

File tree

2 files changed

+87
-44
lines changed

2 files changed

+87
-44
lines changed

modules/angular2/src/change_detection/dynamic_change_detector.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,11 @@ export class DynamicChangeDetector extends AbstractChangeDetector {
157157

158158
var newValue = pipe.transform(context);
159159
if (! ChangeDetectionUtil.noChangeMarker(newValue)) {
160+
var prevValue = this._readSelf(proto);
160161
this._writeSelf(proto, newValue);
161162
this._setChanged(proto, true);
162163

163164
if (proto.lastInBinding) {
164-
var prevValue = this._readSelf(proto);
165165
return ChangeDetectionUtil.simpleChange(prevValue, newValue);
166166
} else {
167167
return null;

modules/angular2/test/change_detection/change_detection_spec.js

Lines changed: 86 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import {Parser} from 'angular2/src/change_detection/parser/parser';
77
import {Lexer} from 'angular2/src/change_detection/parser/lexer';
88

99
import {ChangeDispatcher, DynamicChangeDetector, ChangeDetectionError, ContextWithVariableBindings,
10-
PipeRegistry, NO_CHANGE,
11-
CHECK_ALWAYS, CHECK_ONCE, CHECKED, DETACHED} from 'angular2/change_detection';
10+
PipeRegistry, NO_CHANGE, CHECK_ALWAYS, CHECK_ONCE, CHECKED, DETACHED} from 'angular2/change_detection';
11+
12+
import {ChangeDetectionUtil} from 'angular2/src/change_detection/change_detection_util';
1213

1314

1415
import {JitProtoChangeDetector, DynamicProtoChangeDetector} from 'angular2/src/change_detection/proto_change_detector';
@@ -189,52 +190,90 @@ export function main() {
189190

190191
expect(dispatcher.log).toEqual(["memo=BvalueA"]);
191192
});
193+
194+
describe("change notification", () => {
195+
describe("simple checks", () => {
196+
it("should pass a change record to the dispatcher", () => {
197+
var person = new Person('bob');
198+
var c = createChangeDetector('name', 'name', person);
199+
var cd = c["changeDetector"];
200+
var dispatcher = c["dispatcher"];
192201

193-
describe("group changes", () => {
194-
it("should notify the dispatcher when a group of records changes", () => {
195-
var pcd = createProtoChangeDetector();
196-
pcd.addAst(ast("1 + 2"), "memo", "1");
197-
pcd.addAst(ast("10 + 20"), "memo", "1");
198-
pcd.addAst(ast("100 + 200"), "memo2", "2");
202+
cd.detectChanges();
199203

200-
var dispatcher = new TestDispatcher();
201-
var cd = pcd.instantiate(dispatcher);
204+
var changeRecord = dispatcher.changeRecords[0][0];
205+
206+
expect(changeRecord.bindingMemento).toEqual('name');
207+
expect(changeRecord.change.currentValue).toEqual('bob');
208+
expect(changeRecord.change.previousValue).toEqual(ChangeDetectionUtil.unitialized());
209+
});
210+
});
211+
212+
describe("pipes", () => {
213+
it("should pass a change record to the dispatcher", () => {
214+
var registry = new FakePipeRegistry('pipe', () => new CountingPipe());
215+
216+
var person = new Person('bob');
217+
var c = createChangeDetector('name', 'name | pipe', person, registry);
218+
var cd = c["changeDetector"];
219+
var dispatcher = c["dispatcher"];
220+
221+
cd.detectChanges();
202222

203-
cd.detectChanges();
223+
var changeRecord = dispatcher.changeRecords[0][0];
204224

205-
expect(dispatcher.loggedValues).toEqual([[3, 30], [300]]);
225+
expect(changeRecord.bindingMemento).toEqual('name');
226+
expect(changeRecord.change.currentValue).toEqual('bob state:0');
227+
expect(changeRecord.change.previousValue).toEqual(ChangeDetectionUtil.unitialized());
228+
});
206229
});
207230

208-
it("should notify the dispatcher before switching to the next group", () => {
209-
var pcd = createProtoChangeDetector();
210-
pcd.addAst(ast("a()"), "a", "1");
211-
pcd.addAst(ast("b()"), "b", "2");
212-
pcd.addAst(ast("c()"), "c", "2");
231+
describe("group changes", () => {
232+
it("should notify the dispatcher when a group of records changes", () => {
233+
var pcd = createProtoChangeDetector();
234+
pcd.addAst(ast("1 + 2"), "memo", "1");
235+
pcd.addAst(ast("10 + 20"), "memo", "1");
236+
pcd.addAst(ast("100 + 200"), "memo2", "2");
213237

214-
var dispatcher = new TestDispatcher();
215-
var cd = pcd.instantiate(dispatcher);
238+
var dispatcher = new TestDispatcher();
239+
var cd = pcd.instantiate(dispatcher);
240+
241+
cd.detectChanges();
216242

217-
var tr = new TestRecord();
218-
tr.a = () => {
219-
dispatcher.logValue('InvokeA');
220-
return 'a'
221-
};
222-
tr.b = () => {
223-
dispatcher.logValue('InvokeB');
224-
return 'b'
225-
};
226-
tr.c = () => {
227-
dispatcher.logValue('InvokeC');
228-
return 'c'
229-
};
230-
cd.setContext(tr);
231-
232-
cd.detectChanges();
233-
234-
expect(dispatcher.loggedValues).toEqual(['InvokeA', ['a'], 'InvokeB', 'InvokeC', ['b', 'c']]);
243+
expect(dispatcher.loggedValues).toEqual([[3, 30], [300]]);
244+
});
245+
246+
it("should notify the dispatcher before switching to the next group", () => {
247+
var pcd = createProtoChangeDetector();
248+
pcd.addAst(ast("a()"), "a", "1");
249+
pcd.addAst(ast("b()"), "b", "2");
250+
pcd.addAst(ast("c()"), "c", "2");
251+
252+
var dispatcher = new TestDispatcher();
253+
var cd = pcd.instantiate(dispatcher);
254+
255+
var tr = new TestRecord();
256+
tr.a = () => {
257+
dispatcher.logValue('InvokeA');
258+
return 'a'
259+
};
260+
tr.b = () => {
261+
dispatcher.logValue('InvokeB');
262+
return 'b'
263+
};
264+
tr.c = () => {
265+
dispatcher.logValue('InvokeC');
266+
return 'c'
267+
};
268+
cd.setContext(tr);
269+
270+
cd.detectChanges();
271+
272+
expect(dispatcher.loggedValues).toEqual(['InvokeA', ['a'], 'InvokeB', 'InvokeC', ['b', 'c']]);
273+
});
235274
});
236275
});
237-
276+
238277
describe("enforce no new changes", () => {
239278
it("should throw when a record gets changed after it has been checked", () => {
240279
var pcd = createProtoChangeDetector();
@@ -576,6 +615,7 @@ class TestData {
576615
class TestDispatcher extends ChangeDispatcher {
577616
log:List;
578617
loggedValues:List;
618+
changeRecords:List;
579619
onChange:Function;
580620

581621
constructor() {
@@ -589,21 +629,24 @@ class TestDispatcher extends ChangeDispatcher {
589629
clear() {
590630
this.log = ListWrapper.create();
591631
this.loggedValues = ListWrapper.create();
632+
this.changeRecords = ListWrapper.create();
592633
}
593634

594635
logValue(value) {
595636
ListWrapper.push(this.loggedValues, value);
596637
}
597638

598-
onRecordChange(group, updates:List) {
599-
var value = updates[0].change.currentValue;
600-
var memento = updates[0].bindingMemento;
639+
onRecordChange(group, changeRecords:List) {
640+
var value = changeRecords[0].change.currentValue;
641+
var memento = changeRecords[0].bindingMemento;
601642
ListWrapper.push(this.log, memento + '=' + this._asString(value));
602643

603-
var values = ListWrapper.map(updates, (r) => r.change.currentValue);
644+
var values = ListWrapper.map(changeRecords, (r) => r.change.currentValue);
604645
ListWrapper.push(this.loggedValues, values);
605646

606-
this.onChange(group, updates);
647+
ListWrapper.push(this.changeRecords, changeRecords);
648+
649+
this.onChange(group, changeRecords);
607650
}
608651

609652

0 commit comments

Comments
 (0)