如何在ngFor指令中访问组件的ID?

时间:2017-08-09 13:23:41

标签: angular

如果这是重复,我道歉,但我发现很难得到答案,因为我不确定我是否提出了正确的问题。

我想画一个小svg吧(多次)作为ngFor。

的一部分

让我们说,我有......

list.component.ts

import { Component } from '@angular/core';

@Component({
    selector: 'app-list',
    template: `
        <div *ngFor="let item of items">
            <app-svgbar [value]="someNumber"></app-svgbar>
        </div>`
})

export class ListComponent {

    items: number[] = [0,1,2,3,4,5,6,7,8,9]

}

svgbar.component.ts

import { Component, OnInit, Input } from '@angular/core';
import * as SVG from 'svg.js';

@Component({
    selector: 'app-svgbar',
    template: `<div id="barID"></div>`
})

export class SvgSingleBarComponent implements OnInit {

    @Input() value: number;

    ngOnInit() {
        this.drawSvg(this.value)
    }

    drawSvg( value ) {
        let draw = SVG('barID').size(10, 10) // This is my problem
        draw.rect(value, 10)
        .fill('#000')
    }
}

当它运行时,它会在id="barID"的第一个实例中创建我的所有svg元素

我不确定这样做的正确方法。任何帮助将不胜感激。

Plnkr link

2 个答案:

答案 0 :(得分:1)

传入@Input()作为SVG的索引,您可以将其连接到ID以使其唯一。或者,或者为每个SVG组件上的ID生成随机字符串。

连接示例:

@Component({
    selector: 'app-svgbar',
    template: `<div id="barID-{{index}}"></div>`
})
export class SvgSingleBarComponent implements OnInit {
    @Input() index: number;
    @Input() value: number;

    ngOnInit() {
        this.drawSvg(this.value)
    }

    drawSvg( value ) {
        let draw = SVG('barID-' + this.index).size(10, 10) // This is my problem
        draw.rect(value, 10)
        .fill('#000')
    }
}

在父组件的循环中,请务必传入索引:

    <div *ngFor="let item of items; let i = index">
        <app-svgbar [value]="someNumber" [index]="i"></app-svgbar>
    </div>`

如果您不想处理索引,可以为每个SVG组件设置随机生成的ID:

@Component({
    selector: 'app-svgbar',
    template: `<div id="{{randomID}}"></div>`
})
export class SvgSingleBarComponent implements OnInit {
    @Input() value: number;

    randomID: string = (Math.random() * 1000000000).toString();

    ngOnInit() {
        this.drawSvg(this.value)
    }

    drawSvg( value ) {
        let draw = SVG(this.randomID).size(10, 10) // This is my problem
        draw.rect(value, 10)
        .fill('#000')
    }
}

修改

您可能在这里甚至不需要身份证。只需注入ElementRef并将其用于您的唯一元素访问。

import { ..., ElementRef } from '@angular/core';

constructor(private el: ElementRef) {}

drawSvg( value ) {
    let draw = SVG(this.el.nativeElement).size(10, 10)
}

执行上述操作,一切似乎完美无误。我会展示一个Plnkr示例,但它不会让我保存你的Plnkr,因为它是一个嵌入链接。

答案 1 :(得分:1)

您的问题是如何使用SVG库。

这是你的Plunker,工作:https://plnkr.co/edit/lqEdlw0uo7P1bqb8w6sT?p=preview

您不需要和索引来跟踪元素来实现此目的。 只需将nativeElement添加到SVG lib用法。

这段代码可以解决问题。

import { Component, OnInit, Input, NgZone, ElementRef } from '@angular/core';
import { id } from "@swimlane/ngx-datatable/release/utils";

@Component({
  selector: 'app-svg',
  template: `<div id="bar-{{index}}"></div>`,
  styles: []
})
export class SVGComponent implements OnInit {

  @Input() value: number;
  @Input() index: number;

  constructor(public ngZone: NgZone, public elementRef: ElementRef) {}

  ngOnInit() {
    this.drawSVG()
  }

  drawSVG() {
    let id = 'bar-' + this.index;
    // console.log('id: ',id);
    // console.log('value: ',this.value);
    this.ngZone.run(() => {
      console.log(id);
      let draw = SVG(this.elementRef.nativeElement).size(100, 10)
      draw.rect(10*this.value,10)
      .radius(4)
      .fill('#3db8db')  
    });
  }

} 

NgZone只是为了确保angular会呈现第三方lib的更改。