【问题标题】:Angular2 How to get reference of HTML elements generated dynamicallyAngular2如何获取动态生成的HTML元素的引用
【发布时间】:2017-03-24 22:02:59
【问题描述】:

我有这个动态生成的输入:

  <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}}我想根据这个动态ID获得对DOM元素的引用。此输入可以是 3、6 或更多输入,因此我需要动态访问 id 并保留它。

【问题讨论】:

  • 你想完成什么?
  • @yurzui 我需要在按下按钮时获取所有输入的值,问题是它们的数量和内容可能会有所不同,例如它们可以是 3 个输入或 6 个输入或 4 个或5...所以我需要一些方法来生成动态 id 并动态获取它们的内容
  • 能访问dom就够了吗?
  • @quindimildev 如果我可以访问他们的价值并知道他们的身份,那将会很有用

标签: angular angular2-template angular2-directives


【解决方案1】:

您可以通过elementRef 访问DOM

通过你的构造函数注入它

constructor(myElement: ElementRef) { ... }

并通过nativeElement 属性访问DOM 元素

myElement.nativeElement.select("#blabla")

【讨论】:

  • elementRef.nativeElement 没有 select 方法。
  • 应该是myElement.nativeElement.select('#blabla')
【解决方案2】:

有一个类叫ElementRef class

它允许您直接访问当前组件或托管 DOM 的指令。

您可以使用ElementRef.nativeElement 获取HTML 元素,然后您可以使用Angular 2 提供的jQueryRenderer 类访问html 元素属性进行修改。

ElementRefRenderer 为例:

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');
    }
}

【讨论】:

    【解决方案3】:

    使用@angular/core 中的ElementRef 类获取父元素,然后创建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);
      }
    }
    

    Working Plunker

    编辑:我在这里使用 jQuery 仅用于快速演示。否则,您不应将 jQueryAngular 一起使用。

    【讨论】:

    • 你不应该包含你不推荐做的事情的代码演示,除了这个问题从未提到过使用 jQuery。
    • @wrldbt: "quick demo"
    • 在一个完全不同的框架的代码示例中使用 jQuery 会分散注意力并且不理想。 Angular 的一个强有力的案例是它不必直接绑定到 Web 界面。学习如何使用 Angular 为让您服务于多种不同的媒体而设置的抽象层是我们作为开发人员应该努力教给其他人的东西。
    • 我必须同意反对者的观点。在 Angular 应用程序中包含 jQuery 的答案不仅违反直觉,而且假定您熟悉 jQuery,并且是字面上的反模式。 downvote 是一种技术性问题,但技术性问题是使堆栈溢出令人敬畏的原因。
    【解决方案4】:

    唯一的回应是

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

    不需要其他角度怪异的仪式

    在 Angular 4+ 上测试

    【讨论】:

    • 不知道为什么那个仪式评论让我发笑
    • 只是要评论一下这个 Angular 有一个奇怪的仪式是有原因的。它不适用于所有只会发布到 Web 的开发人员,但 Angular 的长期目标是创建一个可以跨设备使用的统一应用程序开发平台。使用这样的文档函数使得这成为不可能,因为其他平台/目标可能不会以相同的方式实现文档。
    • 很有趣,但我们离跨平台产品还很遥远……来自 Google 的 Flutter 似乎是他们下一个非常大的跨平台产品。我想我们永远不会得到任何有角度的跨平台。
    • @DavidF.,Ionic 和 NativeScript 怎么样?这两种工具都允许我们构建基于 Angular 的混合应用程序
    • 离子很好,我每天都用。再加上新的 Ionic 4,您使用常规的 Angular cli,Ionic 4 和 Angular 7 完全相同。我认为本机脚本不起作用。
    【解决方案5】:

    如果你有多个选择器,你可以使用@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());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-21
      • 2018-09-24
      • 1970-01-01
      • 2013-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-19
      相关资源
      最近更新 更多