Угловой 8 - Как запросить элементы DOM по их атрибутам? - PullRequest
1 голос
/ 30 сентября 2019

У меня есть динамически сгенерированная таблица HTML 5 с использованием рендерера2:

const td = this.renderer.createElement('td');
this.renderer.setProperty(td, 'id', letter + i);
this.renderer.setAttribute(td, 'contenteditable', 'true');
this.renderer.setAttribute(td, 'r', i + '');
this.renderer.setAttribute(td, 'c', j + '');

Таблица имеет следующую структуру

<table _ngcontent-iji-c1="" appcreatereport="">
<tr _ngcontent-iji-c1="">
<td _ngcontent-iji-c1="">1</td>
<td _ngcontent-iji-c1="" id="A1" contenteditable="true" r="1" c="1"></td>
<td _ngcontent-iji-c1="" id="B1" contenteditable="true" r="1" c="2"></td>
<td _ngcontent-iji-c1="" id="C1" contenteditable="true" r="1" c="3"></td>
<td _ngcontent-iji-c1="" id="D1" contenteditable="true" r="1" c="4"></td>
<td _ngcontent-iji-c1="" id="E1" contenteditable="true" r="1" c="5"></td>
</tr>
...

Каждый <td> имеет "id",номер строки "r" и номер столбца "c"

Я пытаюсь работать только с угловыми значениями (поэтому без jquery), и я посмотрел на многие существующие сетки данных, но они никогда полностью не покрывают то, что япланировать и расширять их кажется более сложным, чем создавать именно то, что мне нужно.

У меня два вопроса.

  1. Я обязуюсь не манипулировать DOM напрямую вAngular, как я могу получить доступ к элементам, если они не имеют локальной ссылки? (или как добавить локальную ссылку, когда я генерирую элементы <td> в рендерере2. Текст в <TD> необходимо будет обновить, например, когда я делаю копирование / вставку из Excel.
  2. Как я могу запросить элемент по атрибутам, поэтому я хочу, чтобы элемент с r = 1 и c = 4 (вместо запроса по идентификатору "D1"). Я нашел только @ViewChild, который работает только со ссылками.

В настоящее время я устанавливаю текст элемента TD следующим образом:

(document.getElementById(
          'C1'
        ) as HTMLTableDataCellElement).innerHTML = '123;

Как я могу сделать это более "угловым" способом?

Ответы [ 2 ]

1 голос
/ 30 сентября 2019

Немного неясно, что вы хотите. Но вот пример из нескольких сценариев :

  1. Установка флажка фильтрует список
  2. При щелчке элемента обновляется другой элемент со значением

Сначала просто фиктивный класс:

  export class RowData {
  Name:string;
  Id:number;
  Row:number;
  Column: number;
  Visible: boolean = true;
}

С фиктивными данными:

items: RowData[] = [
         {
          Name: "One",
          Id:1,
          Row:1,
          Column:1,
          Visible:true,
        },
        {
          Name: "Two",
          Id:2,
          Row:2,
          Column:2,
          Visible:true,
        },
        {
          Name: "Another Row",
          Id:5,
          Row:3,
          Column:3,
          Visible:true,
        },
        {
          Name: "Yep",
          Id:4,
          Row:4,
          Column:4,
          Visible:true,
        },
      ]
    }

Для представления у меня есть двухстороннее связывание с парой событий:

<hello name="{{ name }}"></hello>
<p>
  Start editing to see some magic happen :)
</p>
<div>
  <input type="checkbox" name="Toggle Row" (click)="toggleRows()" /> Toggle Rows <br>  
</div>
<div *ngFor="let item of items">
  <div (click)="showMe(item)" *ngIf=item.Visible>{{item.Name}}</div>
</div>

<label *ngIf="clicked">{{clicked.Name}}</label>

А вот события и их зависимые свойства:

toggleRow2Col2: boolean = true;
  clicked: RowData;

  showMe(elem){
    this.clicked = elem;
  }

  toggleRows(){
    this.toggleRow2Col2 = !this.toggleRow2Col2;

    if (!this.toggleRow2Col2){    
    this.items.forEach(function(item){
      if (item.Row != 2 && item.Column != 2){
        item.Visible = false;
      }
    })
    }

    else {
      this.items.forEach(function(item)      {
          item.Visible = true;
      })
    }
  }

Идея в том, что да, мы можем фильтровать и изменять DOM, только по атрибутам и привязке, а не от JS / JQuery.

1 голос
/ 30 сентября 2019

Лучшим способом было бы изменить дизайн, чтобы использовать таблицу с массивом элементов и *ngFor. Чтобы удалить его со страницы, вы можете использовать *ngIf="elements.length === 0";

let elements = [{r:1, c: 1, value:''}, {r:1, c: 2, value:''} ... ];
elements[1].value = '123';

<td *ngFor="let el of elements" [r] = "el.r" [c]="el.c">{{el.value}}<\td>

. В таком случае вы будете иметь доступ к каждому td значению напрямую, используя массив элементов.

В качестве альтернативы- ng-template может использоваться для хранения таблицы в html, но не показывается, пока не понадобится.

...