Skip to content

Commit 8ccafb0

Browse files
committed
feat(view): reimplemented property setters using change detection
1 parent 8a92a1f commit 8ccafb0

36 files changed

Lines changed: 510 additions & 469 deletions

modules/angular2/change_detection.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export {ProtoChangeDetector, ChangeDispatcher, ChangeDetector, ChangeDetection}
1818
export {CHECK_ONCE, CHECK_ALWAYS, DETACHED, CHECKED, ON_PUSH, DEFAULT} from './src/change_detection/constants';
1919
export {DynamicProtoChangeDetector, JitProtoChangeDetector} from './src/change_detection/proto_change_detector';
2020
export {BindingRecord} from './src/change_detection/binding_record';
21-
export {DirectiveRecord} from './src/change_detection/directive_record';
21+
export {DirectiveIndex, DirectiveRecord} from './src/change_detection/directive_record';
2222
export {DynamicChangeDetector} from './src/change_detection/dynamic_change_detector';
2323
export {ChangeDetectorRef} from './src/change_detection/change_detector_ref';
2424
export {PipeRegistry} from './src/change_detection/pipes/pipe_registry';

modules/angular2/src/change_detection/binding_record.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {isPresent, isBlank} from 'angular2/src/facade/lang';
22
import {SetterFn} from 'angular2/src/reflection/types';
33
import {AST} from './parser/ast';
4-
import {DirectiveRecord} from './directive_record';
4+
import {DirectiveIndex, DirectiveRecord} from './directive_record';
55

66
const DIRECTIVE="directive";
77
const ELEMENT="element";
@@ -11,14 +11,16 @@ export class BindingRecord {
1111
mode:string;
1212
ast:AST;
1313

14+
implicitReceiver:any; //number | DirectiveIndex
1415
elementIndex:number;
1516
propertyName:string;
1617
setter:SetterFn;
1718

1819
directiveRecord:DirectiveRecord;
1920

20-
constructor(mode:string, ast:AST, elementIndex:number, propertyName:string, setter:SetterFn, directiveRecord:DirectiveRecord) {
21+
constructor(mode:string, implicitReceiver:any, ast:AST, elementIndex:number, propertyName:string, setter:SetterFn, directiveRecord:DirectiveRecord) {
2122
this.mode = mode;
23+
this.implicitReceiver = implicitReceiver;
2224
this.ast = ast;
2325

2426
this.elementIndex = elementIndex;
@@ -49,14 +51,18 @@ export class BindingRecord {
4951
}
5052

5153
static createForDirective(ast:AST, propertyName:string, setter:SetterFn, directiveRecord:DirectiveRecord) {
52-
return new BindingRecord(DIRECTIVE, ast, 0, propertyName, setter, directiveRecord);
54+
return new BindingRecord(DIRECTIVE, 0, ast, 0, propertyName, setter, directiveRecord);
5355
}
5456

5557
static createForElement(ast:AST, elementIndex:number, propertyName:string) {
56-
return new BindingRecord(ELEMENT, ast, elementIndex, propertyName, null, null);
58+
return new BindingRecord(ELEMENT, 0, ast, elementIndex, propertyName, null, null);
59+
}
60+
61+
static createForHostProperty(directiveIndex:DirectiveIndex, ast:AST, propertyName:string) {
62+
return new BindingRecord(ELEMENT, directiveIndex, ast, directiveIndex.elementIndex, propertyName, null, null);
5763
}
5864

5965
static createForTextNode(ast:AST, elementIndex:number) {
60-
return new BindingRecord(TEXT_NODE, ast, elementIndex, null, null, null);
66+
return new BindingRecord(TEXT_NODE, 0, ast, elementIndex, null, null, null);
6167
}
6268
}

modules/angular2/src/change_detection/change_detection_jit_generator.es6

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {List, ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/faca
33

44
import {AbstractChangeDetector} from './abstract_change_detector';
55
import {ChangeDetectionUtil} from './change_detection_util';
6-
import {DirectiveRecord} from './directive_record';
6+
import {DirectiveIndex, DirectiveRecord} from './directive_record';
77

88
import {
99
ProtoRecord,
@@ -81,12 +81,12 @@ function hydrateTemplate(type:string, mode:string, fieldDefinitions:string, pipe
8181
directiveFieldNames:List<String>, detectorFieldNames:List<String>):string {
8282
var directiveInit = "";
8383
for(var i = 0; i < directiveFieldNames.length; ++i) {
84-
directiveInit += `${directiveFieldNames[i]} = directives.getDirectiveFor(this.directiveRecords[${i}]);\n`;
84+
directiveInit += `${directiveFieldNames[i]} = directives.getDirectiveFor(this.directiveRecords[${i}].directiveIndex);\n`;
8585
}
8686

8787
var detectorInit = "";
8888
for(var i = 0; i < detectorFieldNames.length; ++i) {
89-
detectorInit += `${detectorFieldNames[i]} = directives.getDetectorFor(this.directiveRecords[${i}]);\n`;
89+
detectorInit += `${detectorFieldNames[i]} = directives.getDetectorFor(this.directiveRecords[${i}].directiveIndex);\n`;
9090
}
9191

9292
return `
@@ -313,18 +313,18 @@ export class ChangeDetectorJITGenerator {
313313
}
314314
315315
getDirectiveFieldNames():List<string> {
316-
return this.directiveRecords.map((d) => this.getDirective(d));
316+
return this.directiveRecords.map((d) => this.getDirective(d.directiveIndex));
317317
}
318318
319319
getDetectorFieldNames():List<string> {
320-
return this.directiveRecords.filter(r => r.isOnPushChangeDetection()).map((d) => this.getDetector(d));
320+
return this.directiveRecords.filter(r => r.isOnPushChangeDetection()).map((d) => this.getDetector(d.directiveIndex));
321321
}
322322
323-
getDirective(d:DirectiveRecord) {
323+
getDirective(d:DirectiveIndex) {
324324
return `this.directive_${d.name}`;
325325
}
326326
327-
getDetector(d:DirectiveRecord) {
327+
getDetector(d:DirectiveIndex) {
328328
return `this.detector_${d.name}`;
329329
}
330330
@@ -359,7 +359,7 @@ export class ChangeDetectorJITGenerator {
359359
for (var i = dirs.length - 1; i >= 0; --i) {
360360
var dir = dirs[i];
361361
if (dir.callOnAllChangesDone) {
362-
var directive = `this.directive_${dir.name}`;
362+
var directive = `this.directive_${dir.directiveIndex.name}`;
363363
notifications.push(onAllChangesDoneTemplate(directive));
364364
}
365365
}
@@ -425,7 +425,7 @@ export class ChangeDetectorJITGenerator {
425425
}
426426
427427
genUpdateCurrentValue(r:ProtoRecord):string {
428-
var context = this.localNames[r.contextIndex];
428+
var context = this.getContext(r);
429429
var newValue = this.localNames[r.selfIndex];
430430
var args = this.genArgs(r);
431431
@@ -463,6 +463,14 @@ export class ChangeDetectorJITGenerator {
463463
}
464464
}
465465
466+
getContext(r:ProtoRecord):string {
467+
if (r.contextIndex == -1) {
468+
return this.getDirective(r.directiveIndex);
469+
} else {
470+
return this.localNames[r.contextIndex];
471+
}
472+
}
473+
466474
ifChangedGuard(r:ProtoRecord, body:string):string {
467475
return ifChangedGuardTemplate(r.args.map((a) => this.changeNames[a]), body);
468476
}
@@ -491,7 +499,7 @@ export class ChangeDetectorJITGenerator {
491499
492500
var br = r.bindingRecord;
493501
if (br.isDirective()) {
494-
var directiveProperty = `${this.getDirective(br.directiveRecord)}.${br.propertyName}`;
502+
var directiveProperty = `${this.getDirective(br.directiveRecord.directiveIndex)}.${br.propertyName}`;
495503
return updateDirectiveTemplate(oldValue, newValue, directiveProperty);
496504
} else {
497505
return updateElementTemplate(oldValue, newValue);
@@ -513,7 +521,7 @@ export class ChangeDetectorJITGenerator {
513521
genNotifyOnChanges(r:ProtoRecord):string{
514522
var br = r.bindingRecord;
515523
if (r.lastInDirective && br.callOnChange()) {
516-
return notifyOnChangesTemplate(this.getDirective(br.directiveRecord));
524+
return notifyOnChangesTemplate(this.getDirective(br.directiveRecord.directiveIndex));
517525
} else {
518526
return "";
519527
}
@@ -522,7 +530,7 @@ export class ChangeDetectorJITGenerator {
522530
genNotifyOnPushDetectors(r:ProtoRecord):string{
523531
var br = r.bindingRecord;
524532
if (r.lastInDirective && br.isOnPushChangeDetection()) {
525-
return notifyOnPushDetectorsTemplate(this.getDetector(br.directiveRecord));
533+
return notifyOnPushDetectorsTemplate(this.getDetector(br.directiveRecord.directiveIndex));
526534
} else {
527535
return "";
528536
}

modules/angular2/src/change_detection/coalesce.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ function _selfRecord(r:ProtoRecord, contextIndex:number, selfIndex:number):Proto
4545
[],
4646
r.fixedArgs,
4747
contextIndex,
48+
r.directiveIndex,
4849
selfIndex,
4950
r.bindingRecord,
5051
r.expressionAsString,
@@ -72,6 +73,7 @@ function _replaceIndices(r:ProtoRecord, selfIndex:number, indexMap:Map) {
7273
args,
7374
r.fixedArgs,
7475
contextIndex,
76+
r.directiveIndex,
7577
selfIndex,
7678
r.bindingRecord,
7779
r.expressionAsString,
Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
11
import {ON_PUSH} from './constants';
22
import {StringWrapper} from 'angular2/src/facade/lang';
33

4-
export class DirectiveRecord {
4+
export class DirectiveIndex {
55
elementIndex:number;
66
directiveIndex:number;
7+
8+
constructor(elementIndex:number, directiveIndex:number) {
9+
this.elementIndex = elementIndex;
10+
this.directiveIndex = directiveIndex;
11+
}
12+
13+
get name() {
14+
return `${this.elementIndex}_${this.directiveIndex}`;
15+
}
16+
}
17+
18+
export class DirectiveRecord {
19+
directiveIndex:DirectiveIndex;
720
callOnAllChangesDone:boolean;
821
callOnChange:boolean;
922
changeDetection:string;
1023

11-
constructor(elementIndex:number, directiveIndex:number,
12-
callOnAllChangesDone:boolean, callOnChange:boolean, changeDetection:string) {
13-
this.elementIndex = elementIndex;
24+
constructor(directiveIndex:DirectiveIndex, callOnAllChangesDone:boolean, callOnChange:boolean, changeDetection:string) {
1425
this.directiveIndex = directiveIndex;
1526
this.callOnAllChangesDone = callOnAllChangesDone;
1627
this.callOnChange = callOnChange;
@@ -20,8 +31,4 @@ export class DirectiveRecord {
2031
isOnPushChangeDetection():boolean {
2132
return StringWrapper.equals(this.changeDetection, ON_PUSH);
2233
}
23-
24-
get name() {
25-
return `${this.elementIndex}_${this.directiveIndex}`;
26-
}
2734
}

modules/angular2/src/change_detection/dynamic_change_detector.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {List, ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/faca
33

44
import {AbstractChangeDetector} from './abstract_change_detector';
55
import {BindingRecord} from './binding_record';
6-
import {DirectiveRecord} from './directive_record';
76
import {PipeRegistry} from './pipes/pipe_registry';
87
import {ChangeDetectionUtil, uninitialized} from './change_detection_util';
98

@@ -111,12 +110,12 @@ export class DynamicChangeDetector extends AbstractChangeDetector {
111110

112111
if (proto.lastInDirective) {
113112
if (isPresent(changes)) {
114-
this._getDirectiveFor(directiveRecord).onChange(changes);
113+
this._getDirectiveFor(directiveRecord.directiveIndex).onChange(changes);
115114
changes = null;
116115
}
117116

118117
if (isChanged && bindingRecord.isOnPushChangeDetection()) {
119-
this._getDetectorFor(directiveRecord).markAsCheckOnce();
118+
this._getDetectorFor(directiveRecord.directiveIndex).markAsCheckOnce();
120119
}
121120

122121
isChanged = false;
@@ -129,7 +128,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector {
129128
for (var i = dirs.length - 1; i >= 0; --i) {
130129
var dir = dirs[i];
131130
if (dir.callOnAllChangesDone) {
132-
this._getDirectiveFor(dir).onAllChangesDone();
131+
this._getDirectiveFor(dir.directiveIndex).onAllChangesDone();
133132
}
134133
}
135134
}
@@ -138,7 +137,8 @@ export class DynamicChangeDetector extends AbstractChangeDetector {
138137
if (isBlank(bindingRecord.directiveRecord)) {
139138
this.dispatcher.notifyOnBinding(bindingRecord, change.currentValue);
140139
} else {
141-
bindingRecord.setter(this._getDirectiveFor(bindingRecord.directiveRecord), change.currentValue);
140+
var directiveIndex = bindingRecord.directiveRecord.directiveIndex;
141+
bindingRecord.setter(this._getDirectiveFor(directiveIndex), change.currentValue);
142142
}
143143
}
144144

@@ -150,12 +150,12 @@ export class DynamicChangeDetector extends AbstractChangeDetector {
150150
}
151151
}
152152

153-
_getDirectiveFor(directive:DirectiveRecord) {
154-
return this.directives.getDirectiveFor(directive);
153+
_getDirectiveFor(directiveIndex) {
154+
return this.directives.getDirectiveFor(directiveIndex);
155155
}
156156

157-
_getDetectorFor(directive:DirectiveRecord) {
158-
return this.directives.getDetectorFor(directive);
157+
_getDetectorFor(directiveIndex) {
158+
return this.directives.getDetectorFor(directiveIndex);
159159
}
160160

161161
_check(proto:ProtoRecord) {
@@ -235,6 +235,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector {
235235
var pipe = this._pipeFor(proto, context);
236236

237237
var newValue = pipe.transform(context);
238+
238239
if (! ChangeDetectionUtil.noChangeMarker(newValue)) {
239240
var prevValue = this._readSelf(proto);
240241
this._writeSelf(proto, newValue);
@@ -272,6 +273,12 @@ export class DynamicChangeDetector extends AbstractChangeDetector {
272273
}
273274

274275
_readContext(proto:ProtoRecord) {
276+
if (proto.contextIndex == -1) {
277+
return this._getDirectiveFor(proto.directiveIndex);
278+
} else {
279+
return this.values[proto.contextIndex];
280+
}
281+
275282
return this.values[proto.contextIndex];
276283
}
277284

modules/angular2/src/change_detection/parser/ast.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ export class AstVisitor {
450450

451451
export class AstTransformer {
452452
visitImplicitReceiver(ast:ImplicitReceiver) {
453-
return new ImplicitReceiver();
453+
return ast;
454454
}
455455

456456
visitInterpolation(ast:Interpolation) {

modules/angular2/src/change_detection/proto_change_detector.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {DynamicChangeDetector} from './dynamic_change_detector';
2828
import {ChangeDetectorJITGenerator} from './change_detection_jit_generator';
2929
import {PipeRegistry} from './pipes/pipe_registry';
3030
import {BindingRecord} from './binding_record';
31+
import {DirectiveIndex} from './directive_record';
3132

3233
import {coalesce} from './coalesce';
3334

@@ -153,7 +154,7 @@ class _ConvertAstIntoProtoRecords {
153154
}
154155

155156
visitImplicitReceiver(ast:ImplicitReceiver) {
156-
return 0;
157+
return this.bindingRecord.implicitReceiver;
157158
}
158159

159160
visitInterpolation(ast:Interpolation) {
@@ -247,9 +248,15 @@ class _ConvertAstIntoProtoRecords {
247248

248249
_addRecord(type, name, funcOrValue, args, fixedArgs, context) {
249250
var selfIndex = ++ this.contextIndex;
250-
ListWrapper.push(this.protoRecords,
251-
new ProtoRecord(type, name, funcOrValue, args, fixedArgs, context, selfIndex,
252-
this.bindingRecord, this.expressionAsString, false, false));
251+
if (context instanceof DirectiveIndex) {
252+
ListWrapper.push(this.protoRecords,
253+
new ProtoRecord(type, name, funcOrValue, args, fixedArgs, -1, context, selfIndex,
254+
this.bindingRecord, this.expressionAsString, false, false));
255+
} else {
256+
ListWrapper.push(this.protoRecords,
257+
new ProtoRecord(type, name, funcOrValue, args, fixedArgs, context, null, selfIndex,
258+
this.bindingRecord, this.expressionAsString, false, false));
259+
}
253260
return selfIndex;
254261
}
255262
}

modules/angular2/src/change_detection/proto_record.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {List} from 'angular2/src/facade/collection';
22
import {BindingRecord} from './binding_record';
3+
import {DirectiveIndex} from './directive_record';
34

45
export const RECORD_TYPE_SELF = 0;
56
export const RECORD_TYPE_CONST = 1;
@@ -19,7 +20,10 @@ export class ProtoRecord {
1920
funcOrValue:any;
2021
args:List;
2122
fixedArgs:List;
23+
2224
contextIndex:number;
25+
directiveIndex:DirectiveIndex;
26+
2327
selfIndex:number;
2428
bindingRecord:BindingRecord;
2529
lastInBinding:boolean;
@@ -32,6 +36,7 @@ export class ProtoRecord {
3236
args:List,
3337
fixedArgs:List,
3438
contextIndex:number,
39+
directiveIndex:DirectiveIndex,
3540
selfIndex:number,
3641
bindingRecord:BindingRecord,
3742
expressionAsString:string,
@@ -43,7 +48,10 @@ export class ProtoRecord {
4348
this.funcOrValue = funcOrValue;
4449
this.args = args;
4550
this.fixedArgs = fixedArgs;
51+
4652
this.contextIndex = contextIndex;
53+
this.directiveIndex = directiveIndex;
54+
4755
this.selfIndex = selfIndex;
4856
this.bindingRecord = bindingRecord;
4957
this.lastInBinding = lastInBinding;

0 commit comments

Comments
 (0)