Я пытаюсь создать выбор, который будет изменять размер в соответствии с шириной выбранного элемента.

Вот реализация в jQuery / Javascript: Ширина раскрывающегося списка подходит для текста выбранного элемента

У меня проблема в том, что стили всегда пусты. Если я пытаюсь установить mainSelectElement в hiddenSelectElement, он почти исчезает. Причина в том, что nativeElement.style.width пустое. Я зарегистрировал свойство style в консоли, и каждое свойство пусто. У нас также есть глобальные стили, применяемые для выбора, и они тоже не появляются.

Кто-нибудь знает, почему мои стили пусты? Это как-то связано с теневым DOM? И лучше всего, какие-либо решения?

import { Component, Input, Output, EventEmitter, forwardRef, ViewChild, ElementRef, Renderer } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

const SELECT_RESIZE_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useClass: forwardRef(() => SamSelectResizableComponent),
  multi: true
}

@Component({
  selector: 'sam-select-resizable',
  template: `
    <select #mainSelectElement [ngModel]="selected" (ngModelChange)="updateSelected($event)">
      <ng-content></ng-content>
    </select>

    <select #hiddenSelectElement>
      <option >{{selected}}</option>
    </select>
  `,
  providers: [
    SELECT_RESIZE_VALUE_ACCESSOR
  ]
})
export class SamSelectResizableComponent implements ControlValueAccessor {

  @ViewChild('hiddenSelectElement') hiddenSelectElement: ElementRef;
  @ViewChild('mainSelectElement') mainSelectElement: ElementRef; 

  public selected: any;

  private onChangeCallback: (_: any) => void = (_: any) => {};
  private onTouchedCallback: () => void = () => {};

  get value(): any {
    return this.selected;
  }

  set value(val: any) {
    if (val !== this.selected) {
      this.selected = val;
      this.onChangeCallback(this.selected);
    }
  }

  constructor(private renderer: Renderer) {}

  updateSelected(event) {
    this.selected = event;
    const hiddenWidth = this.hiddenSelectElement.nativeElement.style.width;
    this.renderer.setElementStyle(this.mainSelectElement.nativeElement, 'width', hiddenWidth);
  }

  writeValue(value: any) {
    if (value !== this.selected) {
      this.selected = value;
      this.onChangeCallback(this.selected);
    }
  }

  registerOnChange(fn: any) {
    this.onChangeCallback = fn;
  }

  registerOnTouched(fn: any) {
    this.onTouchedCallback = fn;
  }
}
3
Colin Alford 30 Мар 2017 в 21:28

2 ответа

Лучший ответ

Вы должны брать ширину из nativeElement напрямую, а не из style

const hiddenWidth = this.hiddenSelectElement.nativeElement.clientWidth; //.width
4
Pankaj Parkar 30 Мар 2017 в 18:42

Вот хороший способ получить стили после их применения. Изначально все свойства стиля пусты для любого элемента HTML.

window.getComputedStyle () может решить вашу проблему.

// fetch styles for an element
style = window.getComputedStyle(hiddenSelectElement.nativeElement, null);

// fetch the property values for any style attribute
console.log(style.getPropertyValue("width"));

Для псевдоэлементов, таких как ::before и ::after

// fetch styles for an element
style = window.getComputedStyle(hiddenSelectElement.nativeElement, ':before');

// fetch the property values for any style attribute
console.log(style.getPropertyValue("width"));

Ссылка: https://developer.mozilla.org/en-US / документы / Web / API / Window / getComputedStyle

5
Amit Chigadani 29 Ноя 2017 в 14:33