Удалить селектор элементов HTML хоста, созданный компонентом angular
В angular 2 svg-rect - это компонент, который создает rect, как показано ниже,
<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>
но это не сделает rect из-за созданных специальных тегов элементов. Если теги svg-rect удалены, он отображает 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>
В angular 1.x есть replace: 'true', который удаляет теги директивы с помощью скомпилированного вывода. Можем ли мы реализовать то же самое в angular2?
Ответы
Ответ 1
Вместо того, чтобы пытаться избавиться от элемента-хоста, превратите его в тот, который является допустимым SVG, но другим мудрым unaffecting: вместо вашего селектора элементов
selector: "svg-rect"
и соответствующий ему элемент в шаблоне:
template: `...<svg-rect>...</svg-rect>...`
переключиться на селектор атрибутов:
selector: "[svg-rect]"
и добавьте этот атрибут в тег элемента группы:
template: `...<g svg-rect>...</g>...`
Это будет расширяться до:
<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>
который является действительным SVG, который будет отображать.
Plnkr
Ответ 2
Другой подход для удаления хоста компонента, который я использую.
Директива 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);
}
}
Использование этой директивы;
<avatar [name]="hero.name" remove-host></avatar>
В директиве remove-host
все дочерние элементы nativeElement
вставлены перед хостом, а затем удаляется элемент хоста.
Пример примера Gist
На основе варианта использования может быть несколько проблем с производительностью.
Ответ 3
Другой подход, по которому мы можем получить шаблон компонента из компонента.
Сначала мы создаем компонент, чей тег мы надеемся удалить из браузера (мы не пытаемся удалить тег здесь.)
@Component({
selector: 'tl-no-tag',
template: `
<template #tmp>
<p>{{value}}</p>
</template>`,
styleUrls: []
})
export class TlNoTagComponent {
@ViewChild('tmp') tmp: any;
value = 5;
}
Затем в другом шаблоне компонента мы пишем:
<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 -->
Тогда у нас в браузере что-то вроде этого:
<tl-no-tag></tl-no-tag>
<p>5</p>
Итак, мы вывели <p>{{value}}</p>
из TlNoTagComponent. <tl-no-tag></tl-no-tag>
будет продолжать существовать, но не будет блокировать какие-либо css или svg-thing.
Ответ 4
Чтобы процитировать Angular от 1 до Angular 2 док-документа стратегии обновления:
Директивы, которые заменяют свой хост-элемент (replace: true директивы в Angular 1), не поддерживаются в Angular 2. Во многих случаях эти директивы могут быть обновлены до стандартных директив компонентов.
Бывают случаи, когда регулярные директивы компонентов не работают, в таких случаях могут использоваться альтернативные подходы. Например, для svg см. https://github.com/mhevery/ng2-svg