You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 10中如何用SVG连接不同组件内动态创建的div?

Solution for Drawing Lines Between Dynamic Elements in Angular 10 SVG

Hey there! Let's work through this problem of drawing a line between your dynamic elements el1 and el2 in the SVG component. First, let's fix the obvious typo in your code, then break down how to calculate the correct coordinates.

Step 1: Fix the ID Typo

First, you're accidentally grabbing el1 twice for both elements. Let's correct that line:

const elTwoHtml: HTMLElement | null = document.getElementById('el2'); // Fixed ID from el1 to el2

Step 2: Understand Coordinate Systems

The key here is converting the viewport-relative coordinates (from getBoundingClientRect()) to container-relative coordinates since your SVG is absolutely positioned inside the containerRef div.

Here's what you need to account for:

  • getBoundingClientRect() returns positions relative to the browser's viewport, not the parent container.
  • Your SVG is positioned absolutely inside containerRef, so we need to subtract the container's viewport position from the elements' viewport positions to get coordinates relative to the container.
  • For a clean line, you'll probably want to connect the centers of el1 and el2 instead of their top-left corners.

Step 3: Calculate the Line Coordinates

Here's the updated createLine() method with full coordinate calculation. We'll also add safety checks in case the elements haven't rendered yet (since they're dynamic):

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

// ... your component decorator here

export class LineComponent {
  @ViewChild('containerRef') containerRef!: ElementRef;

  public linePositionX1 = 0;
  public linePositionY1 = 0;
  public linePositionX2 = 0;
  public linePositionY2 = 0;

  public createLine(): void {
    // Grab the elements (with null checks)
    const elOneHtml: HTMLElement | null = document.getElementById('el1');
    const elTwoHtml: HTMLElement | null = document.getElementById('el2');
    const containerElement = this.containerRef.nativeElement;

    if (!elOneHtml || !elTwoHtml || !containerElement) {
      console.warn('One or more elements/container not found');
      return;
    }

    // Get viewport-relative rects
    const parentDomRect: DOMRect = containerElement.getBoundingClientRect();
    const elOneRect: DOMRect = elOneHtml.getBoundingClientRect();
    const elTwoRect: DOMRect = elTwoHtml.getBoundingClientRect();

    // Account for container scroll (if your container is scrollable)
    const containerScrollLeft = containerElement.scrollLeft;
    const containerScrollTop = containerElement.scrollTop;

    // Calculate center coordinates relative to the container
    // For el1
    this.linePositionX1 = (elOneRect.left + elOneRect.width / 2) - parentDomRect.left + containerScrollLeft;
    this.linePositionY1 = (elOneRect.top + elOneRect.height / 2) - parentDomRect.top + containerScrollTop;

    // For el2
    this.linePositionX2 = (elTwoRect.left + elTwoRect.width / 2) - parentDomRect.left + containerScrollLeft;
    this.linePositionY2 = (elTwoRect.top + elTwoRect.height / 2) - parentDomRect.top + containerScrollTop;
  }
}

Key Explanations:

  • Null Checks: We make sure all elements exist before calculations to avoid runtime errors, especially since el1 and el2 are dynamically created.
  • Center Calculation: Adding element.width/2 and element.height/2 to the top-left position gives us the element's center point.
  • Scroll Adjustment: If your container is scrollable, we add containerScrollLeft and containerScrollTop to correct for any scrolling that shifts the elements' positions relative to the container.

Step 4: Ensure the Method Runs at the Right Time

Since el1 and el2 are dynamically created, you need to call createLine() after these elements are rendered in the DOM. Some common ways to do this:

  • Use ngAfterViewChecked() (but add a guard to avoid infinite loops, since this runs on every change detection cycle).
  • Trigger createLine() from the component that dynamically creates el1/el2 (e.g., after a data load or component initialization).
  • Use a ViewChild with ngAfterViewInit() if the elements are part of a child component's template.

Bonus: Clean Up SVG Positioning

Make sure your container has position: relative so the absolute-positioned SVG is correctly contained within it:

.container {
  position: relative;
  /* Add other styles like width, height as needed */
}

内容的提问来源于stack exchange,提问作者Anna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 00:07:30