Как получить ширину элемента (DOM) в Angular2
есть некоторые подобные темы, но я не мог найти подходящего ответа для моих нужд. Так что прямого доступа DOM следует строго избегать в angular2 мне просто интересно, какая лучшая практика для этого.
чего я не хочу достичь, это изменение размера элемента на основе текущего ширина.
workitemresize.деталь.ТС
import { Directive, ElementRef, HostListener, Renderer, Input } from '@angular/core';
@Directive({
selector: '[workItemResize]'
})
export class WorkItemResizeDirective implements ngAfterViewInit {
private el: HTMLElement;
private renderer: Renderer;
constructor(el: ElementRef, public renderer: Renderer)
{
this.el = el.nativeElement;
this.renderer = renderer;
}
@HostListener('window:resize', ['$event.target'])
onResize()
{
this.resizeWorks();
}
ngAfterViewInit() {
this.resizeWorks();
}
private resizeWorks(): void {
this.renderer.setElementStyle(this.el, 'height', this.el.width); // <-- doesn't work I kow that this.el.width doesn't exist but just for demonstration purpose
this.renderer.setElementStyle(this.el, 'height', '500'); // <-- works
}
}
проектов.шаблон.HTML-код
<div class="posts row">
<div class="work-item col-xs-12 col-sm-6 col-no-padding" workItemResize *ngFor="let post of posts">
<!-- show some fancy image -->
<div class="img" [ngStyle]="{'background-image':'url('+post.better_featured_image.source_url+')'}"></div>
</div>
</div>
4 ответов
Я не знаю, как получить ширину от элемента хоста без доступа nativeElement
но настройка может быть сделано так:
@HostListener('window:resize', ['$event.target'])
onResize() {
this.resizeWorks();
}
@HostBinding('style.height.px')
elHeight:number;
private resizeWorks(): void {
this.elHeight = this.el.nativeElement.width;
}
Если вы можете добавить элемент внутри шаблона компонентов, например
<div style="width: 100%;" #div (window:resize)="elHeight = div.getBoundingClientRect()">
<!-- your template here -->
</div>
тогда это будет работать без прямого доступа DOM вообще (но не после init).
я попробовал @ günterzöchbauer решение и усовершенствовал его. Вам не нужен HostListener для получения границ div. Как и с "click" или другим событием (event)="function ()", он запустит эту функцию. Надеюсь кто-то найдет это полезным.
<div #div (window:resize)="onResize(div.getBoundingClientRect())">
<!-- your template here -->
</div>
onResize() {
this.resizeWorks();
}
@HostBinding('style.height.px') elHeight:number;
private resizeWorks(): void {
this.elHeight = this.el.nativeElement.width;
}
(#div) - это переменная, необходимая для получения цели измерения. Это не должно быть то же имя, что и элемент, это может быть любое имя.
еще один способ получить размеры элементов-использовать класс ElementRef из углового ядра, но затем вы должны найти тот дочерний элемент, который имеет свойства width и height. Я использовал это в угловых картах 2, чтобы получить ширину и высоту контейнера, но я узнал, что, используя этот метод, я должен был найти в элементе элемент дерева, который имел эти свойства, и это был второй дочерний элемент корневого элемента. Это более грязно. ElementDimensions-это просто класс с высотой и шириной, который я сделал, чтобы содержать эти свойства.
<div (window:resize)="onResize()">
<!-- your template here -->
</div>
private getContainerDimensions(): ElementDimensions{
var rootElement = this.elementRef.nativeElement;
var childElement = rootElement.firstElementChild;
var contentElement = childElement.firstElementChild;
return {
height:contentElement.clientHeight,
width: contentElement.clientWidth
};
}
Я проверял этот способ и просто работал! Похоже, что связывание сделало эту работу.
<div #foto [style.height.px]="foto.getBoundingClientRect().width / 2">
вы можете получить ширину самого компонента, если он имеет определенное свойство отображения (например, "блок" в приведенном ниже примере). Обратите внимание, что вы должны иметь возможность определить этот стиль (используя DOM shadowing):
:host {
display:block;
}
Если вы не используете DOM shadowing (Ionic 2-3):
my-component {
display:block;
}
вот контроллер (выставляя ширину как наблюдаемую):
import {AfterViewInit, Component, ElementRef, HostListener, Input} from '@angular/core';
import {Subject} from 'rxjs/Subject';
@Component({
selector: 'my-component',
template: '{{$width|async}}',
style: 'my-component {display: block;}'
})
export class MyComponent implements AfterViewInit {
@Input() public gridWidth: number;
private $width: Subject<number> = new Subject();
constructor(private elementRef: ElementRef) {
}
public ngAfterViewInit(): void {
this.emitWidth();
}
@HostListener('window:resize', ['$event.target'])
public onResize(): void {
this.emitWidth();
}
private emitWidth(): void {
this.$width.next(this.getWidth());
}
private getWidth(): number {
return this.getNativeElement().clientWidth;
}
private getNativeElement(): HTMLElement {
return this.elementRef.nativeElement;
}
}