fix(compiler): don't trigger duplicated directives
Fixes #2756 Closes #2568
This commit is contained in:
parent
0b50258814
commit
0598226e24
|
@ -153,8 +153,8 @@ export class Compiler {
|
|||
}
|
||||
}
|
||||
|
||||
var boundDirectives =
|
||||
ListWrapper.map(directives, (directive) => this._bindDirective(directive));
|
||||
var boundDirectives = this._removeDuplicatedDirectives(
|
||||
ListWrapper.map(directives, (directive) => this._bindDirective(directive)));
|
||||
|
||||
var renderTemplate = this._buildRenderTemplate(component, view, boundDirectives);
|
||||
pvPromise =
|
||||
|
@ -167,6 +167,12 @@ export class Compiler {
|
|||
return pvPromise;
|
||||
}
|
||||
|
||||
private _removeDuplicatedDirectives(directives: List<DirectiveBinding>): List<DirectiveBinding> {
|
||||
var directivesMap: Map<number, DirectiveBinding> = new Map();
|
||||
directives.forEach((dirBinding) => { directivesMap.set(dirBinding.key.id, dirBinding); });
|
||||
return MapWrapper.values(directivesMap);
|
||||
}
|
||||
|
||||
private _compileNestedProtoViews(componentBinding, renderPv, directives): Promise<AppProtoView>|
|
||||
AppProtoView {
|
||||
var protoViews =
|
||||
|
|
|
@ -299,6 +299,40 @@ export function main() {
|
|||
.then((rootTC) => { async.done(); });
|
||||
}));
|
||||
|
||||
it('should execute a given directive once, even if specified multiple times',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(MyComp, new viewAnn.View({
|
||||
template: '<p no-duplicate></p>',
|
||||
directives: [
|
||||
DuplicateDir,
|
||||
DuplicateDir,
|
||||
[DuplicateDir, [DuplicateDir, bind(DuplicateDir).toClass(DuplicateDir)]]
|
||||
]
|
||||
}))
|
||||
.createAsync(MyComp)
|
||||
.then((rootTC) => {
|
||||
expect(rootTC.nativeElement).toHaveText('noduplicate');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should use the last directive binding per directive',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(MyComp, new viewAnn.View({
|
||||
template: '<p no-duplicate></p>',
|
||||
directives: [
|
||||
bind(DuplicateDir)
|
||||
.toClass(DuplicateDir),
|
||||
bind(DuplicateDir).toClass(OtherDuplicateDir)
|
||||
]
|
||||
}))
|
||||
.createAsync(MyComp)
|
||||
.then((rootTC) => {
|
||||
expect(rootTC.nativeElement).toHaveText('othernoduplicate');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should support directives where a selector matches property binding',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(MyComp, new viewAnn.View(
|
||||
|
@ -1805,3 +1839,17 @@ class ExportDir {
|
|||
@Component({selector: 'comp'})
|
||||
class ComponentWithoutView {
|
||||
}
|
||||
|
||||
@Directive({selector: '[no-duplicate]'})
|
||||
class DuplicateDir {
|
||||
constructor(renderer: DomRenderer, private elRef: ElementRef) {
|
||||
DOM.setText(elRef.nativeElement, DOM.getText(elRef.nativeElement) + 'noduplicate');
|
||||
}
|
||||
}
|
||||
|
||||
@Directive({selector: '[no-duplicate]'})
|
||||
class OtherDuplicateDir {
|
||||
constructor(renderer: DomRenderer, private elRef: ElementRef) {
|
||||
DOM.setText(elRef.nativeElement, DOM.getText(elRef.nativeElement) + 'othernoduplicate');
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue