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 =
|
var boundDirectives = this._removeDuplicatedDirectives(
|
||||||
ListWrapper.map(directives, (directive) => this._bindDirective(directive));
|
ListWrapper.map(directives, (directive) => this._bindDirective(directive)));
|
||||||
|
|
||||||
var renderTemplate = this._buildRenderTemplate(component, view, boundDirectives);
|
var renderTemplate = this._buildRenderTemplate(component, view, boundDirectives);
|
||||||
pvPromise =
|
pvPromise =
|
||||||
|
@ -167,6 +167,12 @@ export class Compiler {
|
||||||
return pvPromise;
|
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>|
|
private _compileNestedProtoViews(componentBinding, renderPv, directives): Promise<AppProtoView>|
|
||||||
AppProtoView {
|
AppProtoView {
|
||||||
var protoViews =
|
var protoViews =
|
||||||
|
|
|
@ -299,6 +299,40 @@ export function main() {
|
||||||
.then((rootTC) => { async.done(); });
|
.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',
|
it('should support directives where a selector matches property binding',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
tcb.overrideView(MyComp, new viewAnn.View(
|
tcb.overrideView(MyComp, new viewAnn.View(
|
||||||
|
@ -1805,3 +1839,17 @@ class ExportDir {
|
||||||
@Component({selector: 'comp'})
|
@Component({selector: 'comp'})
|
||||||
class ComponentWithoutView {
|
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