Angular2 Как получить ссылку на элементы HTML, сгенерированные динамически

У меня эти входы генерируются динамически:

  <div *ngFor="let cell of column; let i = index;">
          <!-- Material design input-->
          <md-input id="my-input-{{i}}">
          </md-input>
  </div>

Обратите внимание: id=my-input-{{i}} я хочу получить ссылку на элемент DOM на основе этого динамического идентификатора. Этот вход может быть 3, 6 или более входов, поэтому мне нужно получить динамический доступ к идентификатору и удержать его.


person CommonSenseCode    schedule 10.11.2016    source источник
comment
Что вы пытаетесь достичь?   -  person yurzui    schedule 10.11.2016
comment
@yurzui Мне нужно получить значения всех входов нажатием кнопки, проблема в том, что они могут различаться по количеству и содержанию, например, они могут быть 3 входа или 6 входов, или 4 или 5 ... так что мне нужно несколько способ генерировать динамический идентификатор и динамически получать их содержимое   -  person CommonSenseCode    schedule 10.11.2016
comment
достаточно ли, если вы можете получить доступ к дому?   -  person quindimildev    schedule 10.11.2016
comment
plnkr.co/edit/O1VCGMMLPqhaQAXyKzYp?p=preview   -  person yurzui    schedule 10.11.2016
comment
@quindimildev, если бы я мог получить доступ к их значению и узнать их идентификатор, это было бы полезно   -  person CommonSenseCode    schedule 10.11.2016
comment
вы можете получить доступ к дому с помощью ElementRef.naviteElement. Проверьте этот stackoverflow.com/questions/32693061/   -  person quindimildev    schedule 10.11.2016
comment
@quindimildev и как только я получу DOM, как получить доступ к элементу по id=blabla   -  person CommonSenseCode    schedule 10.11.2016
comment
с помощью селектора elementRef.nativeElement.select(#blabla)'. может быть, это не лучшее решение, но я думаю, что это может решить   -  person quindimildev    schedule 10.11.2016
comment
@yurzui, если вы хотите включить ответ, я проголосую и выберу свой ответ tjanks   -  person CommonSenseCode    schedule 10.11.2016
comment
@quindimildev ваши ответы помогают, если вы хотите включить плохой голос, спасибо   -  person CommonSenseCode    schedule 10.11.2016
comment
ответ опубликован, спасибо!   -  person quindimildev    schedule 10.11.2016


Ответы (5)


Единственный ответ

let elem:Element = document.getElementById("myProgrammaticallyChosenIndex")

Никакая другая угловатая странная церемония не нужна

Проверено на угловом 4+

person David F.    schedule 01.10.2017
comment
Не знаю, почему этот комментарий о церемонии заставил меня смеяться. - person Rodrigo; 14.03.2018
comment
просто собираюсь прокомментировать это, что у angular есть странная церемония по какой-то причине. Это не относится ко всем разработчикам, которые когда-либо будут публиковаться только в Интернете, но долгосрочная цель angular — создать единую платформу разработки приложений, которую можно использовать на разных устройствах. Использование подобных функций документа делает это невозможным, поскольку другие платформы/цели могут не реализовать документ таким же образом. - person bryan60; 17.09.2018
comment
Интересно, но мы так далеки от кросс-платформенного продукта... И кажется, что флаттер, исходящий от Google, станет их следующей большой кроссплатформенной вещью. Я предполагаю, что мы никогда не получим угловатую кросс-платформу. - person David F.; 20.09.2018
comment
@DavidF., а как насчет Ionic и NativeScript? Оба инструмента позволяют нам создавать гибридные приложения на основе Angular. - person E. Evsevleev; 22.03.2019
comment
Ionic в порядке, я использую его каждый день. Кроме того, с новым Ionic 4 вы используете обычный angular cli, Ionic 4 и Angular 7 точно такие же. Родной скрипт, я полагаю, не будет работать. - person David F.; 24.03.2019
comment
Но как мы можем это сделать, используя хуки жизненного цикла angular? - person Shivam; 24.06.2020
comment
действительно лучше использовать после ngAfterviewInit - person David F.; 01.07.2020

Используйте класс ElementRef из @angular/core, чтобы получить родительский элемент, а затем создайте HTMLElement, чтобы получить его динамические элементы по имени класса.

Компонент:

declare var $: any; //intentional use of jQuery-not recommended though

@Component({
  selector: 'my-app',
  template: `
    <input type='button' (click)='addDiv()' value='Add New Div' />

    <input type='button' (click)='selectDiv()' value='Select' />
  `
})
export class App {
  constructor(private elRef: ElementRef) {
  }

  addDiv() {
    /*intentional use of jQuery for appending new div
     give a class to your dynamic elements*/

    $('my-app').append("<div class='foo'>Hello I'm Dynamic!</div>");
  }

  selectDiv() {
    //create a new HTMLElement from nativeElement
    var hElement: HTMLElement = this.elRef.nativeElement;

    //now you can simply get your elements with their class name
    var allDivs = hElement.getElementsByClassName('foo');

    //do something with selected elements
    console.log(allDivs);
  }
}

Рабочий планкер

Изменить: здесь я использовал jQuery только для быстрой демонстрации. В противном случае не следует использовать jQuery с Angular.

person Syed Ali Taqi    schedule 23.12.2016
comment
Вы не должны включать демонстрацию кода для чего-то, что вы не рекомендуете делать, кроме того факта, что в вопросе никогда не упоминалось использование jQuery. - person wrldbt; 21.11.2017
comment
@wrldbt: quick demo - person Syed Ali Taqi; 21.11.2017
comment
Использование jQuery в образце кода для совершенно другого фреймворка отвлекает и не идеально. Одним из сильных аргументов в пользу Angular является то, что его не нужно напрямую привязывать к веб-интерфейсу. Изучение того, как использовать уровни абстракции, созданные Angular, чтобы позволить вам обслуживать несколько разных сред, — это то, чему мы, как разработчики, должны стремиться научить других. - person jetset; 12.09.2018
comment
Я должен согласиться с downvoters. Ответ, включающий jQuery в приложение Angular, не только нелогичен, он предполагает знакомство с jQuery, а также является буквальным анти-шаблоном. Понижение — это техническая особенность, но именно технические детали делают переполнение стека потрясающим. - person dudewad; 14.12.2018

Если у вас есть несколько селекторов, вы можете использовать @ViewChildren. // HTML

<div *ngFor="let cell of column; let i = index;">
          <!-- Material design input-->
          <md-input id="my-input-{{i}}" #inputBinding>
          </md-input>
  </div>

// TS-файл

@ViewChildren('inputBinding') inputBinding: QueryList<ComponentName>;

ngAfterViewInit(){
 console.log(this.inputBinding.toArray());
}
person Sai Prasad    schedule 09.04.2021

Существует класс с именем класс ElementRef.

Это дает вам разрешение на прямой доступ к текущему компоненту или директиве, в которой находится DOM.

Вы можете использовать ElementRef.nativeElement для получения элемента HTML, затем вы можете получить доступ к свойствам элемента html, чтобы внести изменения, используя jQuery или Renderer, предоставляемый Angular 2.

Пример с ElementRef и Renderer:

import { Directive, ElementRef, Input, Renderer } from '@angular/core';
@Directive({ selector: '[myHighlight]' })
export class HighlightDirective {
    constructor(el: ElementRef, renderer: Renderer) {
       renderer.setElementStyle(el.nativeElement, 'backgroundColor', 'yellow');
    }
}
person Bo Chen    schedule 10.11.2016

Вы можете получить доступ к DOM через elementRef.

Вставьте его через свой конструктор с помощью

constructor(myElement: ElementRef) { ... }

И получить доступ к элементу DOM по свойству nativeElement

myElement.nativeElement.select("#blabla")
person quindimildev    schedule 10.11.2016
comment
elementRef.nativeElement не имеет метода select. - person Pete Gardner; 16.06.2017
comment
должно быть myElement.nativeElement.select('#blabla') - person ya_dimon; 28.09.2018