根据 DOM 元素使用函数绑定属性

问题描述 投票:0回答:1

我正在尝试将以下代码改编为 Angular,涉及 Text 元素:

function setAxisValue(name, value)
{
    var axis = document.getElementById(name)
    if(!axis)
        return

    var text = document.getElementById(name+"Text")
    if(!text)
        return

    axis.style.width = ((100*value).toFixed(1) + "%");

    text.innerHTML = ((100*value).toFixed(0) + "%");
    if (text.offsetWidth > axis.offsetWidth)
        text.style.visibility = "hidden";
    else
        text.style.visibility = "visible";
}

这适用于大量元素,具体取决于不同的名称和相应的值。
我通过使用

{{...}}
插值解决了 innerHTML 部分,并使用
[style.width]="..."
解决了宽度部分(当然使用表达式而不是省略号)。
但我不知道如何做可见性的事情,如下:

<span id="...Text" [style.visibility]="getVisibility()">

在语法方面是可行的,但问题是该函数需要访问其被调用的 DOM 元素,以提取其 offsetWidth 及其父元素的 offsetWidth (是的,axis 元素系统地是文本元素的父元素)。

我怎样才能做到这一点?


我追求的一些想法:

事件侦听器语法

(keyup)="..."

 有一个特殊变量 
$event
 来访问引发调用的事件(或将其传递给函数),但是没有匹配的 
$element
 用于方括号属性绑定(这会给出方便的
[style.visibility]="getVisibility($element)"
)。

我读到了有关在 Component 类的某种 onInit 方法中添加一些代码的内容,以向受选择器表达式约束的所有元素添加回调。好的方面是 DOM 元素可用于回调,因为它是我调用 addEventListener 的对象。不好的方面是我不知道它应该监听什么事件:可见性的驱动应该是每次两个元素的 offsetWidth 发生变化时(例如,包括窗口大小调整时)。

最后,我看到了名为 ViewChild / ViewChildren 的东西,据说可以让组件访问 DOM 对象。问题是,我对它了解甚少,选择器似乎与我想要寻找的东西不匹配:

.someclass div span

CSS选择器表达式。相反,它似乎只遵循 Angular 特定的机制来选择 DOM 元素。
另外,假设我在组件中获取了该计算应该发生的所有元素的集合,并将绑定函数
[style.visibility]="getVisibility()"
 附加到每个元素。仍然存在一个问题,当我在函数内部时,我应该猜测哪个元素(在集合中的所有元素中)我应该读取(以及父级的 offsetWidth)的 offsetWidth 来计算和返回可见性。

angular binding
1个回答
0
投票
对于此类场景,您需要重用 DOM 操作并根据元素传入不同的数据。指令是最好的解决方案,您可以将所有 DOM 操作移至指令中。

@Directive({ selector: '[DynamicAxis]', standalone: true, }) export class DynamicAxisDirective { @Input() name!: string; @Input() value: number = 0; constructor(private element: ElementRef, private renderer: Renderer2) {} ngOnChanges() { var axis = document.getElementById(this.name); if (!axis) return; axis.style.width = (100 * this.value).toFixed(1) + '%'; const text = this.element?.nativeElement; text.innerHTML = (100 * this.value).toFixed(0) + '%'; this.renderer.setStyle( text, 'visibility', text.offsetWidth > axis.offsetWidth ? 'hidden' : 'visible' ); } }
我们使用 

[name]="test"

 属性绑定将输入变量作为输入属性传递,并使用它们来执行逻辑。

我们使用

ElementRef

,它是放置指令的元素引用。我将把它放在 span 元素上。

<span id="...Text" DynamicAxisDirective [name]="'test'" [value]="70">
我们可以使用

Renderer2

来设置样式、类等。为什么用这个而不是传统的JS,因为数据会自动处理。

我更希望您传入

axis

 作为模板引用变量,而不是使用 `getElementById,因为这更像是角度方法。

<div id="test" #axis>axis</div> ... <span id="...Text" DynamicAxisDirective [name]="'test'" [value]="70" [axis]="axis">
然后您可以使用这个传入的值并通过 ID 部分删除获取元素。

这样一切都以有角度的方式完成。

© www.soinside.com 2019 - 2024. All rights reserved.