使用 Angular 指令在模板中绘制对象

Posted

技术标签:

【中文标题】使用 Angular 指令在模板中绘制对象【英文标题】:Draw an object in template using Angular directive 【发布时间】:2020-03-09 05:11:05 【问题描述】:

我想使用指令在一系列 div 上方绘制一个三角形

我有四个正方形和两个值:chargenormal

charge 用于确定方块的颜色。 normal画三角形

我已经创建了一个指令来实现它

import  Directive, ElementRef, HostListener, Renderer2, Input, OnInit  from '@angular/core';

@Directive(
  selector: '[squareChart]'
)
export class SquareChartDirective implements OnInit 
  colors = 
    1: '#13a09b',
    2: '#13a03c',
    3: '#eceb1d',
    4: '#d40f0f'
  ;
  @Input() charge: number;
  @Input() normal: number;
  constructor(private el: ElementRef, private renderer: Renderer2) 
  ngOnInit() 
    this.highlight(this.charge);
  
  private highlight(charge: number) 
    let colorCode = Math.trunc(charge / 25) + 1;
    for (let i = 1; i <= colorCode; i++) 
      if (this.el.nativeElement.id === `sqr$i`) 
        this.el.nativeElement.style.backgroundColor = this.colors[i];
      
    
  

我的组件

<div class="container">
  <div class="row">
    <div squareChart id="sqr1" [charge]="actualCharge" [normal]="norm" class="p-2 bd-highlight square" >
    </div>
    <div squareChart id="sqr2" [charge]="actualCharge" [normal]="norm" class="p-2 bd-highlight square" >
    </div>
    <div squareChart id="sqr3" [charge]="actualCharge" [normal]="norm" class="p-2 bd-highlight square" >
    </div>
    <div squareChart id="sqr4" [charge]="actualCharge" [normal]="norm" class="p-2 bd-highlight square">
      </div>
  </div>
</div>

例如,norm = 60,向下的三角形应该在第三个正方形上方(如果是 25,那么在第二个正方形上方等等......)

例子

我不知道如何从同一个指令中做到这一点。

另一种解决方案可能是第一行用于三角形,第二行用于正方形,但我认为这不是最佳选择。

这里是demo

【问题讨论】:

【参考方案1】:

您可以使用Canvas 或使用absolute 定位的SVG 元素绘制三角形,所有这些都在您的directive 内。要使绝对定位起作用,父元素需要定位到relative 到视口。

.square 
  position: relative;
  ...

StackBlitz:在SquareChartDirective 类中,您可以根据需要从当前的drawSVGMarker 切换到drawCanvasMarker 方法。

【讨论】:

应该根据正常百分比值绘制每个正方形代表25%(4个正方形)所以三角形应该是动态的 好的,通过检查hansmaad's 的答案进行条件检查,并相应地更改了我的StackBlitz【参考方案2】:

改用组件。在组件模板中,您可以有条件地隐藏或显示三角形。

(我可能没有理解你的逻辑,但这不是重点,我认为)

@Component(
  selector: 'square-chart',
  template: '<div [ngClass]="hidden: !mark" class="triangle"></div><div [ngStyle]="background:background" class="p-2 bd-highlight square"></div>',
)
export class SquareComponent implements OnInit 
  @Input() i: number;
  @Input() charge: number;
  @Input() normal: number;
  mark = false;
  background;
  colors = 
    1: '#13a09b',
    2: '#13a03c',
    3: '#eceb1d',
    4: '#d40f0f'
  ;

  ngOnInit() 
    this.background = this.colors[this.i];
    this.mark = +this.i === 2;
  


https://stackblitz.com/edit/angular-3kfmgg?file=src/app/app.component.html

【讨论】:

以上是关于使用 Angular 指令在模板中绘制对象的主要内容,如果未能解决你的问题,请参考以下文章

错误多个指令 [bar, bar] 在使用自定义指令和 angular-bootstrap 时要求模板

如何在 Angular 2 指令中使用 templateUrl

Angular.js 指令动态模板URL

在 Angular 中有没有办法将包含组件指令的 html 注入到父组件的模板中?

来自组件的Angular 4调用指令方法

用另一个结构指令包装 Angular ngFor 指令