Angular和SVG:如何动态加载自定义组件?

时间:2018-11-29 20:37:34

标签: angular typescript svg

我需要动态加载SVG项目。

项目非常简单。 模板:

<svg:rect [attr.x]="x" [attr.y]="y" width="10" height="10" />

班级:

export class DraggableSvgItemComponent implements OnInit {

  x: number = 0;
  y: number = 0;

  constructor() { }

  ngOnInit() {
  }

}

这是容器组件模板的样子:

<svg attr.height.px="{{height}}" attr.width.px="{{width}}">
    <svg:g app-draggable-svg-item *ngFor="let d of draggables" />
</svg>

这就是我从容器组件生成项目的方式:

// commands <- load fun stuff with x and y coordinates
var toSet = new Array<DraggableSvgItemComponent>();
commands.forEach((value) => {
  if (value instanceof ZPL2.GraphicShapeBase) {
    var toAdd = new DraggableSvgItemComponent();
    toAdd.x = value.x;
    toAdd.y = value.y;

    console.log(toAdd);
    toSet.push(toAdd);
  }
});

this.draggables = toSet;

控制台日志显示x和y的值非零:DraggableSvgItemComponent {x: 100, y: 50},但输出是一个svg,在左上角有一个正方形,x和y的值为0。

如果我将<rect>直接放在画布上而不使用其他组件,则可以使用,但是我需要它,因为我必须处理不同的svg内容。

我在使用值绑定时出了什么问题?

1 个答案:

答案 0 :(得分:3)

您不必在代码中创建DraggableSvgItemComponent组件。如果将组件选择器定义为属性选择器,它们将被创建为<svg:g>元素的子元素。 xy属性可以用Input decorator标记以允许数据绑定。

@Component({
  selector: '[draggable-svg-item]',
  template: `<svg:rect [attr.x]="x" [attr.y]="y" width="10" height="10" />`
})
export class DraggableSvgItemComponent {
  @Input() x: number = 0;
  @Input() y: number = 0;
}

在父组件中,draggables可以简单地是一个位置数组:

export class AppComponent {
  width = 200;
  height = 200;
  draggables = [
    { x: 5, y: 0 },
    { x: 20, y: 30 },
    { x: 0, y: 20 },
    { x: 24, y: 8 },
  ];
}

通过属性绑定提供给子组件:

<svg [attr.height.px]="height" [attr.width.px]="width">
    <svg:g draggable-svg-item [x]="d.x" [y]="d.y" *ngFor="let d of draggables" />
</svg>

有关演示,请参见this stackblitz