Изменение атрибута <path>'d' без использования getElementBy ... anti-pattern - PullRequest
0 голосов
/ 26 октября 2019

Я сделал сетку для холста в контексте онлайновой рисованной платформы "MS Paint". Для сетки пользователь должен иметь возможность вводить значения для размера квадратов, которые составляют сетку, а также непрозрачность сетки. Я делаю это, используя ngModel (для пользовательского ввода) и ngStyle.

Вот часть HTML-кода, касающегося сетки:

    <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
        <defs>
            <pattern id="smallGrid" patternUnits="userSpaceOnUse" [ngStyle]="setSizePattern()">
                <path id="myPath" fill="none" stroke="black" stroke-width="0.7" [ngStyle]="setSizePath()" />
            </pattern>
        </defs>   
        <rect id="myGrid" width="100%" height="100%" fill="url(#smallGrid)" [ngStyle]="setStyle()"/>
    </svg>

<pattern> имеетатрибуты 'width' и 'height', а <path> имеет атрибут 'd';я хочу изменить эти атрибуты.

Вот соответствующие методы:


  setSizePath(): object {
      const pathString = '"M' + this.userInputGridSize + ',0 L0,0 0,' + this.userInputGridSize + '"';
      const cssPath = 'path(' + pathString + ')';
      return {d: cssPath};
  }

  setSizePattern(): object {
    return {width: this.userInputGridSize,
      height: this.userInputGridSize};
  }


Шаблон <path> атрибут d равен d="MX,0 L0,0 0,X", где X равенразмер квадратов, составляющих сетку. width и height из <pattern> также должны быть X.

Это работает , когда я устанавливаю его вручную в html-файле:

    <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
        <defs>
            <pattern width="10" height="10" id="smallGrid" patternUnits="userSpaceOnUse" [ngStyle]="setSizePattern()">
                <path id="myPath" d="M10,0 L0,0 0,10" fill="none" stroke="black" stroke-width="0.7" [ngStyle]="setSizePath()" />
            </pattern>
        </defs>   
        <rect id="myGrid" width="100%" height="100%" fill="url(#smallGrid)" [ngStyle]="setStyle()"/>
    </svg>

Отображает сетку из квадратов размером 10 (думаю, px).

Я просто не могу изменить ее.

В отличие от этого, функция setStyle(), обнаруженная в <rect> работает отлично:

  setStyle(): object {
    return {opacity: this.userInputOpacity};
  }

О, и вот недопустимая версия (из-за getElementBy ... вещи), которая также работает:

// Functional but code smell size setter

  setSizeSmell(): void {
    const gridElement = document.getElementById('smallGrid');
    const pathElement = document.getElementById('myPath');
    const value = (document.getElementById('sizeInput') as HTMLInputElement).value;
    const pathValue = "M"+ value + ",0 L0,0 0," + value;

    if (gridElement && pathElement) {
      pathElement.setAttribute("d", pathValue);
      gridElement.setAttribute("width", value);
      gridElement.setAttribute("height", value);
    }

  }

sizeInput это поле, гдепользователь вводит желаемое значение для размеров квадрата сетки. Но мы не можем использовать эти методы, потому что они являются анти-шаблонными.

...