Angular и SVG: как динамически загружать компоненты SVG? - PullRequest
0 голосов
/ 01 декабря 2018

в приложении, которое я разрабатываю, у меня есть список команд (GC-> круг, GB-> бокс, GE-> эллипс и т. Д.).Я должен отобразить их в SVG.

Я следовал руководству https://angular.io/guide/dynamic-component-loader, но мне чего-то не хватает в SVG.

Я подготовил компонент для каждой команды (этоуже звучит глупо, потому что код тот же, за исключением шаблона):

@Component({
  selector: '[app-gc]',
  template: '<svg:circle [attr.r]="command.diameter/2" [attr.stroke]="command.borderColor" fill="#000" [attr.stroke-width]="command.borderThickness" />'
})
export class GCComponent implements OnInit, SVGComponent {
  @Input('[command]') command: ZPL2.GraphicShapeBase;
  constructor() { }
}

Компонент, на который я загружаю отрендеренную команду, выглядит так:

@Component({
  selector: '[draggableSVGItem]',
  template: '<svg:g svg-host/>'
})
export class DraggableSvgItemComponent implements OnInit {      
  x: number = 0;
  y: number = 0;
  command: ZPL2.GraphicShapeBase;

  @Input()
  set draggableSVGItem(graphicCommand: ZPL2.GraphicShapeBase) {
    this.command = graphicCommand;
    this.x = graphicCommand.x;
    this.y = graphicCommand.y;
  }
  constructor() { }

  ngOnInit() {
    // Get the appropriate component for the command
    var componentType = null;
    if (this.command instanceof ZPL2.GC) {
      componentType = GCComponent;
    }
    if (this.command instanceof ZPL2.GB) {
      componentType = GBComponent;
    }
    if (this.command instanceof ZPL2.GE) {
      componentType = GEComponent;
    }

    // Get the component factory
    let componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentType);

    // Clear the host view
    let viewContainerRef = this.svgHost.viewContainerRef;
    viewContainerRef.clear();

    // Dynamically create the component and set its command as the current one
    let componentRef = viewContainerRef.createComponent(componentFactory,);
    (<SVGComponent>componentRef.instance).command = this.command;
  }
}

Все работает почти идеально,Проблема, с которой я столкнулся, заключается в том, что при создании компонента SVG-элементы заключаются в DIV, и, следовательно, выходные данные остаются пустыми:

extra div

Я новичок в AngularЕсть ли у вас какие-либо предложения, чтобы избавиться от этого DIV и сделать код проще?

EDIT

Я решил это, следуя примеру по этой ссылке: https://www.chrisjmendez.com/2017/06/17/angular-dynamically-inserting-svg-into-an-element/

Связывая свойство innerHTML элемента, я могу установить различное содержимое SVG в зависимости от типа класса команды:

template: <svg:g [innerHTML]="svg"/>

ngOnInit() {
  // Get the appropriate component for the command
  var html = ``;
  if (this.command instanceof ZPL2.GC) {
    html = `<circle r="` + this.command.diameter / 2 + `" stroke="` + this.command.borderColor + `" fill="#000" stroke-width="` + this.command.borderThickness + `" />`;
  }
  if (this.command instanceof ...

  this.svg = this.sanitizer.bypassSecurityTrustHtml(html);
}

Inтаким образом, мне не нужно создавать компонент для каждой команды.Каждая команда может иметь свой собственный метод getHTML ().

Недостатком является то, что у меня нет привязки к свойствам команды, верно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...