2015-12-15 10 views
26

W kątowa 2, SVG-rect jest elementem, który tworzy rect jak poniżej,Usuń przyjmującego elementu HTML selektorów stworzone przez kątowej komponentu

<svg height="550" width="450" x="0" y="0"> 
    <g id="svgGroup"> 
     <svg-rect> 
     <!--template bindings={}--> 
      <rect x="10" y="10" height="100" width="100" fill="red" stroke="#000" stroke-width="2"></rect> 
     <!--template bindings={}--> 
     </svg-rect> 
     <svg-rect> 
     <!--template bindings={}--> 
      <rect x="10" y="10" height="100" width="100" fill="red" stroke="#000" stroke-width="2"></rect> 
     <!--template bindings={}--> 
     </svg-rect> 
    </g> 
</svg> 

ale to nie uczyni rect ponieważ utworzonych specjalnych tagów elementów. Jeśli SVG-rect znaczniki są usuwane to czyni Rect

<svg height="550" width="450" x="0" y="0"> 
    <g id="svgGroup"> 
     <!--template bindings={}--> 
     <rect x="10" y="10" height="100" width="100" fill="red" stroke="#000" stroke-width="2"></rect> 
     <!--template bindings={}--> 
     <!--template bindings={}--> 
     <rect x="10" y="10" height="100" width="100" fill="red" stroke="#000" stroke-width="2"></rect> 
     <!--template bindings={}--> 
    </g> 
</svg> 

kątowej 1.x, jest wymienić: 'true' który usuwa znaczniki dyrektywy ze skompilowanej wyjścia. Czy możemy to samo wdrożyć w angular2?

Odpowiedz

19

Zamiast próbować pozbyć się elementu przyjmującego, przekształcić go w taki, który jest ważny SVG ale innych mądrych unaffecting: Zamiast swojej elementu selektora

selector: "svg-rect" 

i jego odpowiedniego elementu w szablonie :

template: `...<svg-rect>...</svg-rect>...` 

przełącznik do wyboru atrybutu :

selector: "[svg-rect]" 

i dodać, że atrybut znacznika pierwiastek z grupy:

template: `...<g svg-rect>...</g>...` 

ta rozszerzy się do:

<svg height="550" width="450" x="0" y="0"> 
    <g id="svgGroup"> 
     <g svg-rect> 
     <!--template bindings={}--> 
      <rect x="10" y="10" height="100" width="100" fill="red" stroke="#000" stroke-width="2"></rect> 
     <!--template bindings={}--> 
     </g> 
     <g svg-rect> 
     <!--template bindings={}--> 
      <rect x="10" y="10" height="100" width="100" fill="red" stroke="#000" stroke-width="2"></rect> 
     <!--template bindings={}--> 
     </g> 
    </g> 
</svg> 

który jest ważny SVG, które czynią. Plnkr

+0

Działa to dobrze wszędzie tam, gdzie potrzebny jest prawidłowy element, właśnie użyłem tego dla małego komponentu dla nagłówków tabeli , gdzie występuje ten sam problem. Jedno pytanie brzmi jednak: czy istnieje jakaś dokumentacja, do której można utworzyć łącze? – David

+2

@David - Nie znajdziesz go w podręcznikach (jeszcze), ale aby zapewnić, że jest błogosławiony: Oto wątek, w którym użytkownicy robią przypadek, że czasami (svg i tabele) musisz użyć selektorów atrybutu do modyfikowania struktury : https://github.com/angular/angular/issues/11280. W odpowiedzi, funkcjonalność została dodana (dobrze, przywrócona, faktycznie) tutaj: https://github.com/angular/angular/pull/11808. –

+1

, ale co jeśli chcę dodać wiele elementów w jednym elemencie (ręcznie, nie przez * ngFor) – Marcel

4

Cytując Angular 1 to Angular 2 Upgrade Strategy doc:

dyrektyw, które zastępują ich elementem hosta (wymienić: prawdziwe dyrektyw kątowej 1), nie są obsługiwane w Kątowymi 2. W wielu przypadkach te dyrektywy można zmodernizować w ciągu dyrektyw regularnych składowych .

Istnieją przypadki, w których zwykłe dyrektywy komponentów nie będą działać, w tych przypadkach można zastosować alternatywne podejścia. Na przykład dla svg zobacz: https://github.com/mhevery/ng2-svg

21

Inne podejście do usuwania hosta komponentu, którego używam.

dyrektywa remove-host

//remove the host of avatar to be rendered as svg 
@Directive({ 
    selector: '[remove-host]' 
}) 
class RemoveHost { 
    constructor(private el: ElementRef) { 
    } 

    //wait for the component to render completely 
    ngOnInit() { 
     var nativeElement: HTMLElement = this.el.nativeElement, 
      parentElement: HTMLElement = nativeElement.parentElement; 
     // move all children out of the element 
     while (nativeElement.firstChild) { 
      parentElement.insertBefore(nativeElement.firstChild, nativeElement); 
     } 
     // remove the empty element(the host) 
     parentElement.removeChild(nativeElement); 
    } 
} 

Korzystanie z niniejszej dyrektywy;
<avatar [name]="hero.name" remove-host></avatar>

w dyrektywie remove-host wszystkie dzieci z nativeElement umieszczane przed przyjmującego, a następnie element gospodarza usunięto.

Sample Example Gist
Na podstawie przypadku użycia może wystąpić kilka problemów z wydajnością.

+0

Może to być problem z wydajnością, to jest to, co myślałem na początku. Ale obecnie wykorzystuję ten sposób w moim materialnym projekcie lekkie komponenty do zastąpienia elementu hosta, w przeciwnym razie problemy z wyświetlaniem html – Kuncevic

+0

@Kuncevich Dobrze wiedzieć, że moja odpowiedź pomogła, wąskie gardła wydajności zostaną utworzone, gdy element 'ChangeDetection' zostanie wywołany jako' shadow DOM! == rzeczywisty DOM'. Ale jeśli nie ma wielu elementów, to nie byłoby to tak duże. Mamy nadzieję, że;) – Bhavik

+0

Potrzebujemy jakiejś analogii do Angular1 'replace: true' http://stackoverflow.com/questions/22497706/angular-directive-replace-true Ktoś powiedział, że ta właściwość jest w rzeczywistości kątowa2, ale nieoficjalnie obsługiwana. – Kuncevic

6

Istnieje inne podejście, które pozwala uzyskać szablon elementu ze składnika.
Najpierw tworzymy komponent, którego tag mamy nadzieję usunąć z przeglądarki renderowanie

@Component({ 
    selector: 'tl-no-tag', 
    template: ` 
    <template #tmp> 
     <p>{{value}}</p> 
    </template>`, 
    styleUrls: [] 
}) 
export class TlNoTagComponent { 
    @ViewChild('tmp') tmp: any; 
    value = 5; 
} 

Następnie w szablonie innego komponentu, piszemy (nie starają się usunąć tag tutaj.):

<tl-no-tag #source></tl-no-tag> <!-- This line can be placed anywhere --> 
<template [ngTemplateOutlet]="source.tmp"></template> <!-- This line will be placed where needed --> 

Następnie musimy w coś podobnego przeglądarki to:

<tl-no-tag></tl-no-tag> 
<p>5</p> 

Więc przyniosły <p>{{value}}</p> z TlNoTagComponent . <tl-no-tag></tl-no-tag> będzie nadal tam być, ale nie będzie blokować żadnych plików css lub svg.

+0

"Czy szablon ma własny oddzielny zakres zmiennych, jakie zmienne może zobaczyć szablon?" Sprawdź ten (w części Zawartość szablonu): https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet/ – Timathon

Powiązane problemy