Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit b0e6bd7

Browse files
author
Jason Bedard
committed
perf($compile): remove use of deepEquals and $stateful interceptor from bidi bindings
1 parent 627180f commit b0e6bd7

File tree

2 files changed

+141
-23
lines changed

2 files changed

+141
-23
lines changed

src/ng/compile.js

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3535,7 +3535,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
35353535
optional = definition.optional,
35363536
mode = definition.mode, // @, =, <, or &
35373537
lastValue,
3538-
parentGet, parentSet, compare, removeWatch;
3538+
parentGet, removeWatch;
35393539

35403540
switch (mode) {
35413541

@@ -3576,23 +3576,22 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
35763576
if (optional && !attrs[attrName]) break;
35773577

35783578
parentGet = $parse(attrs[attrName]);
3579-
if (parentGet.literal) {
3580-
compare = equals;
3581-
} else {
3582-
compare = simpleCompare;
3583-
}
3584-
parentSet = parentGet.assign || function() {
3579+
var parentSet = parentGet.assign || function() {
35853580
// reset the change, or we will throw this exception on every $digest
35863581
lastValue = destination[scopeName] = parentGet(scope);
35873582
throw $compileMinErr('nonassign',
35883583
'Expression \'{0}\' in attribute \'{1}\' used with directive \'{2}\' is non-assignable!',
35893584
attrs[attrName], attrName, directive.name);
35903585
};
3586+
var childGet = function childGet() { return destination[scopeName]; };
3587+
35913588
lastValue = destination[scopeName] = parentGet(scope);
3592-
var parentValueWatch = function parentValueWatch(parentValue) {
3593-
if (!compare(parentValue, destination[scopeName])) {
3589+
3590+
var bidiWatchAction = function bidiWatchAction(newValues) {
3591+
var parentValue = newValues[0];
3592+
if (!simpleCompare(parentValue, destination[scopeName])) {
35943593
// we are out of sync and need to copy
3595-
if (!compare(parentValue, lastValue)) {
3594+
if (!simpleCompare(parentValue, lastValue)) {
35963595
// parent changed and it has precedence
35973596
destination[scopeName] = parentValue;
35983597
} else {
@@ -3601,13 +3600,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
36013600
}
36023601
}
36033602
lastValue = parentValue;
3604-
return lastValue;
36053603
};
3606-
parentValueWatch.$stateful = true;
36073604
if (definition.collection) {
3608-
removeWatch = scope.$watchCollection(attrs[attrName], parentValueWatch);
3605+
removeWatch = scope.$watchCollection(parentGet, function bidiCollectionWatchAction(parentValue) { destination[scopeName] = parentValue; });
36093606
} else {
3610-
removeWatch = scope.$watch($parse(attrs[attrName], parentValueWatch), null, parentGet.literal);
3607+
removeWatch = scope.$watchGroup([parentGet, childGet], bidiWatchAction);
36113608
}
36123609
removeWatchCollection.push(removeWatch);
36133610
break;

test/ng/compileSpec.js

Lines changed: 130 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5416,21 +5416,21 @@ describe('$compile', function() {
54165416

54175417
inject(function($rootScope) {
54185418
compile('<div other-tpl-dir param1="::foo" param2="bar"></div>');
5419-
expect(countWatches($rootScope)).toEqual(6); // 4 -> template watch group, 2 -> '='
5419+
expect(countWatches($rootScope)).toEqual(8); // 4 -> template watch group, 2 -> '='
54205420
$rootScope.$digest();
54215421
expect(element.html()).toBe('1:;2:;3:;4:');
5422-
expect(countWatches($rootScope)).toEqual(6);
5422+
expect(countWatches($rootScope)).toEqual(8);
54235423

54245424
$rootScope.foo = 'foo';
54255425
$rootScope.$digest();
54265426
expect(element.html()).toBe('1:foo;2:;3:foo;4:');
5427-
expect(countWatches($rootScope)).toEqual(4);
5427+
expect(countWatches($rootScope)).toEqual(6);
54285428

54295429
$rootScope.foo = 'baz';
54305430
$rootScope.bar = 'bar';
54315431
$rootScope.$digest();
54325432
expect(element.html()).toBe('1:foo;2:bar;3:foo;4:bar');
5433-
expect(countWatches($rootScope)).toEqual(3);
5433+
expect(countWatches($rootScope)).toEqual(5);
54345434

54355435
$rootScope.bar = 'baz';
54365436
$rootScope.$digest();
@@ -5487,18 +5487,18 @@ describe('$compile', function() {
54875487
compile('<div other-tpl-dir param1="::foo" param2="bar"></div>');
54885488
$rootScope.$digest();
54895489
expect(element.html()).toBe('1:;2:;3:;4:');
5490-
expect(countWatches($rootScope)).toEqual(6); // 4 -> template watch group, 2 -> '='
5490+
expect(countWatches($rootScope)).toEqual(8); // 4 -> template watch group, 2 -> '='
54915491

54925492
$rootScope.foo = 'foo';
54935493
$rootScope.$digest();
54945494
expect(element.html()).toBe('1:foo;2:;3:foo;4:');
5495-
expect(countWatches($rootScope)).toEqual(4);
5495+
expect(countWatches($rootScope)).toEqual(6);
54965496

54975497
$rootScope.foo = 'baz';
54985498
$rootScope.bar = 'bar';
54995499
$rootScope.$digest();
55005500
expect(element.html()).toBe('1:foo;2:bar;3:foo;4:bar');
5501-
expect(countWatches($rootScope)).toEqual(3);
5501+
expect(countWatches($rootScope)).toEqual(5);
55025502

55035503
$rootScope.bar = 'baz';
55045504
$rootScope.$digest();
@@ -5771,6 +5771,46 @@ describe('$compile', function() {
57715771
}
57725772
}));
57735773

5774+
it('should work with filtered literal objects within array literals', inject(function() {
5775+
$rootScope.gabName = 'Gabriel';
5776+
$rootScope.tonyName = 'Tony';
5777+
$rootScope.query = '';
5778+
$rootScope.$apply();
5779+
5780+
compile('<div><span my-component reference="[{name: gabName}, {name: tonyName}] | filter:query">');
5781+
5782+
expect(componentScope.reference).toEqual([{name: $rootScope.gabName}, {name: $rootScope.tonyName}]);
5783+
5784+
$rootScope.query = 'Gab';
5785+
$rootScope.$apply();
5786+
5787+
expect(componentScope.reference).toEqual([{name: $rootScope.gabName}]);
5788+
5789+
$rootScope.tonyName = 'Gab';
5790+
$rootScope.$apply();
5791+
5792+
expect(componentScope.reference).toEqual([{name: $rootScope.gabName}, {name: $rootScope.tonyName}]);
5793+
}));
5794+
5795+
it('should work with filtered constant literal objects within array literals (constant)', inject(function() {
5796+
$rootScope.query = '';
5797+
$rootScope.$apply();
5798+
5799+
compile('<div><span my-component reference="[{name: \'Gabriel\'}, {name: \'Toni\'}] | filter:query">');
5800+
5801+
expect(componentScope.reference).toEqual([{name: 'Gabriel'}, {name: 'Toni'}]);
5802+
5803+
$rootScope.query = 'Gab';
5804+
$rootScope.$apply();
5805+
5806+
expect(componentScope.reference).toEqual([{name: 'Gabriel'}]);
5807+
5808+
$rootScope.query = 'i';
5809+
$rootScope.$apply();
5810+
5811+
expect(componentScope.reference).toEqual([{name: 'Gabriel'}, {name: 'Toni'}]);
5812+
}));
5813+
57745814
});
57755815

57765816
});
@@ -5829,8 +5869,48 @@ describe('$compile', function() {
58295869
$rootScope.$apply();
58305870

58315871
expect(componentScope.colref).toEqual([$rootScope.collection[0]]);
5832-
expect(componentScope.colrefAlias).toEqual([$rootScope.collection[0]]);
5833-
expect(componentScope.$colrefAlias).toEqual([$rootScope.collection[0]]);
5872+
expect(componentScope.colrefAlias).toEqual(componentScope.colref);
5873+
expect(componentScope.$colrefAlias).toEqual(componentScope.colref);
5874+
5875+
$rootScope.collection[1].name = 'Gab';
5876+
$rootScope.$apply();
5877+
5878+
expect(componentScope.colref).toEqual($rootScope.collection);
5879+
expect(componentScope.colrefAlias).toEqual(componentScope.colref);
5880+
expect(componentScope.$colrefAlias).toEqual(componentScope.colref);
5881+
}));
5882+
5883+
it('should work with filtered objects within a literal collection', inject(function() {
5884+
$rootScope.gab = {
5885+
name: 'Gabriel',
5886+
value: 18
5887+
};
5888+
$rootScope.tony = {
5889+
name: 'Tony',
5890+
value: 91
5891+
};
5892+
$rootScope.query = '';
5893+
$rootScope.$apply();
5894+
5895+
compile('<div><span my-component colref="[gab, tony] | filter:query" $colref$="[gab, tony] | filter:query">');
5896+
5897+
expect(componentScope.colref).toEqual([$rootScope.gab, $rootScope.tony]);
5898+
expect(componentScope.colrefAlias).toEqual(componentScope.colref);
5899+
expect(componentScope.$colrefAlias).toEqual(componentScope.colref);
5900+
5901+
$rootScope.query = 'Gab';
5902+
$rootScope.$apply();
5903+
5904+
expect(componentScope.colref).toEqual([$rootScope.gab]);
5905+
expect(componentScope.colrefAlias).toEqual(componentScope.colref);
5906+
expect(componentScope.$colrefAlias).toEqual(componentScope.colref);
5907+
5908+
$rootScope.tony.name = 'Gab';
5909+
$rootScope.$apply();
5910+
5911+
expect(componentScope.colref).toEqual([$rootScope.gab, $rootScope.tony]);
5912+
expect(componentScope.colrefAlias).toEqual(componentScope.colref);
5913+
expect(componentScope.$colrefAlias).toEqual(componentScope.colref);
58345914
}));
58355915

58365916
it('should update origin scope when isolate scope changes', inject(function() {
@@ -6187,6 +6267,47 @@ describe('$compile', function() {
61876267
}));
61886268

61896269

6270+
it('should work with filtered literal objects within array literals', inject(function() {
6271+
$rootScope.gabName = 'Gabriel';
6272+
$rootScope.tonyName = 'Tony';
6273+
$rootScope.query = '';
6274+
$rootScope.$apply();
6275+
6276+
compile('<div><span my-component ow-ref="[{name: gabName}, {name: tonyName}] | filter:query">');
6277+
6278+
expect(componentScope.owRef).toEqual([{name: $rootScope.gabName}, {name: $rootScope.tonyName}]);
6279+
6280+
$rootScope.query = 'Gab';
6281+
$rootScope.$apply();
6282+
6283+
expect(componentScope.owRef).toEqual([{name: $rootScope.gabName}]);
6284+
6285+
$rootScope.tonyName = 'Gab';
6286+
$rootScope.$apply();
6287+
6288+
expect(componentScope.owRef).toEqual([{name: $rootScope.gabName}, {name: $rootScope.tonyName}]);
6289+
}));
6290+
6291+
it('should work with filtered constant literal objects within array literals', inject(function() {
6292+
$rootScope.query = '';
6293+
$rootScope.$apply();
6294+
6295+
compile('<div><span my-component ow-ref="[{name: \'Gabriel\'}, {name: \'Toni\'}] | filter:query">');
6296+
6297+
expect(componentScope.owRef).toEqual([{name: 'Gabriel'}, {name: 'Toni'}]);
6298+
6299+
$rootScope.query = 'Gab';
6300+
$rootScope.$apply();
6301+
6302+
expect(componentScope.owRef).toEqual([{name: 'Gabriel'}]);
6303+
6304+
$rootScope.query = 'i';
6305+
$rootScope.$apply();
6306+
6307+
expect(componentScope.owRef).toEqual([{name: 'Gabriel'}, {name: 'Toni'}]);
6308+
}));
6309+
6310+
61906311
describe('literal objects', function() {
61916312
it('should copy parent changes', inject(function() {
61926313
compile('<div><span my-component ow-ref="{name: name}">');

0 commit comments

Comments
 (0)