Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 67d05eb

Browse files
committed
fix(compiler): use DI order for change detection order.
Closes angular#8198
1 parent 152a117 commit 67d05eb

File tree

4 files changed

+78
-6
lines changed

4 files changed

+78
-6
lines changed

modules/angular2/src/compiler/provider_parser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ export class ProviderElementContext {
109109
var sortedProviderTypes =
110110
this._transformedProviders.values().map(provider => provider.token.identifier);
111111
var sortedDirectives = ListWrapper.clone(this._directiveAsts);
112-
ListWrapper.sort(this._directiveAsts,
112+
ListWrapper.sort(sortedDirectives,
113113
(dir1, dir2) => sortedProviderTypes.indexOf(dir1.directive.type) -
114114
sortedProviderTypes.indexOf(dir2.directive.type));
115115
return sortedDirectives;

modules/angular2/src/compiler/template_ast.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,13 @@ export class ElementAst implements TemplateAst {
118118
* Get the component associated with this element, if any.
119119
*/
120120
getComponent(): CompileDirectiveMetadata {
121-
return this.directives.length > 0 && this.directives[0].directive.isComponent ?
122-
this.directives[0].directive :
123-
null;
121+
for (var i = 0; i < this.directives.length; i++) {
122+
var dirAst = this.directives[i];
123+
if (dirAst.directive.isComponent) {
124+
return dirAst.directive;
125+
}
126+
}
127+
return null;
124128
}
125129
}
126130

modules/angular2/test/compiler/template_parser_spec.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ export function main() {
633633
`Mixing multi and non multi provider is not possible for token service0 ("[ERROR ->]<div dirA dirB>"): TestComp@0:0`);
634634
});
635635

636-
it('should sort providers and directives by their DI order', () => {
636+
it('should sort providers by their DI order', () => {
637637
var provider0 = createProvider('service0', {deps: ['type:[dir2]']});
638638
var provider1 = createProvider('service1');
639639
var dir2 = createDir('[dir2]', {deps: ['service1']});
@@ -646,6 +646,20 @@ export function main() {
646646
expect(elAst.providers[3].providers).toEqual([provider0]);
647647
});
648648

649+
it('should sort directives by their DI order', () => {
650+
var dir0 = createDir('[dir0]', {deps: ['type:my-comp']});
651+
var dir1 = createDir('[dir1]', {deps: ['type:[dir0]']});
652+
var dir2 = createDir('[dir2]', {deps: ['type:[dir1]']});
653+
var comp = createDir('my-comp');
654+
var elAst: ElementAst =
655+
<ElementAst>parse('<my-comp dir2 dir0 dir1>', [comp, dir2, dir0, dir1])[0];
656+
expect(elAst.providers.length).toBe(4);
657+
expect(elAst.directives[0].directive).toBe(comp);
658+
expect(elAst.directives[1].directive).toBe(dir0);
659+
expect(elAst.directives[2].directive).toBe(dir1);
660+
expect(elAst.directives[3].directive).toBe(dir2);
661+
});
662+
649663
it('should mark directives and dependencies of directives as eager', () => {
650664
var provider0 = createProvider('service0');
651665
var provider1 = createProvider('service1');

modules/angular2/test/core/linker/change_detection_integration_spec.ts

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,18 @@ export function main() {
10561056
expect(renderLog.log).toEqual([]);
10571057
}));
10581058
});
1059+
1060+
describe('multi directive order', () => {
1061+
it('should follow the DI order for the same element', fakeAsync(() => {
1062+
var ctx =
1063+
createCompFixture('<div orderCheck2="2" orderCheck0="0" orderCheck1="1"></div>');
1064+
1065+
ctx.detectChanges(false);
1066+
ctx.destroy();
1067+
1068+
expect(directiveLog.filter(['set'])).toEqual(['0.set', '1.set', '2.set']);
1069+
}));
1070+
});
10591071
});
10601072
}
10611073

@@ -1066,7 +1078,10 @@ const ALL_DIRECTIVES = CONST_EXPR([
10661078
forwardRef(() => TestLocals),
10671079
forwardRef(() => CompWithRef),
10681080
forwardRef(() => EmitterDirective),
1069-
forwardRef(() => PushComp)
1081+
forwardRef(() => PushComp),
1082+
forwardRef(() => OrderCheckDirective2),
1083+
forwardRef(() => OrderCheckDirective0),
1084+
forwardRef(() => OrderCheckDirective1),
10701085
]);
10711086

10721087
const ALL_PIPES = CONST_EXPR([
@@ -1296,6 +1311,45 @@ class TestDirective implements OnInit, DoCheck, OnChanges, AfterContentInit, Aft
12961311
}
12971312
}
12981313

1314+
@Directive({selector: '[orderCheck0]'})
1315+
class OrderCheckDirective0 {
1316+
private _name: string;
1317+
1318+
@Input('orderCheck0')
1319+
set name(value: string) {
1320+
this._name = value;
1321+
this.log.add(this._name, 'set');
1322+
}
1323+
1324+
constructor(public log: DirectiveLog) {}
1325+
}
1326+
1327+
@Directive({selector: '[orderCheck1]'})
1328+
class OrderCheckDirective1 {
1329+
private _name: string;
1330+
1331+
@Input('orderCheck1')
1332+
set name(value: string) {
1333+
this._name = value;
1334+
this.log.add(this._name, 'set');
1335+
}
1336+
1337+
constructor(public log: DirectiveLog, _check0: OrderCheckDirective0) {}
1338+
}
1339+
1340+
@Directive({selector: '[orderCheck2]'})
1341+
class OrderCheckDirective2 {
1342+
private _name: string;
1343+
1344+
@Input('orderCheck2')
1345+
set name(value: string) {
1346+
this._name = value;
1347+
this.log.add(this._name, 'set');
1348+
}
1349+
1350+
constructor(public log: DirectiveLog, _check1: OrderCheckDirective1) {}
1351+
}
1352+
12991353
@Directive({selector: '[testLocals]'})
13001354
class TestLocals {
13011355
constructor(templateRef: TemplateRef, vcRef: ViewContainerRef) {

0 commit comments

Comments
 (0)