简体   繁体   English

如何在Angular应用程序中显示简单的abcjs表?

[英]How to display a simple abcjs sheet in an Angular application?

Using the abcjs library in an Angular 7 application, I have the following template: Angular 7应用程序中使用abcjs库,我有以下模板:

<div id="{{device.name}}"></div>

with the controller: 与控制器:

@Component({
  selector: 'midi-sheet',
  templateUrl: './sheet.component.html',
  styleUrls: ['./sheet.component.css']
})
export class SheetComponent implements AfterViewInit, OnDestroy  {

  // devices$: Observable<Array<Device>>;
  @Input() device: Device;

  constructor(
    // private storeService: StoreService,
    private sheetService: SheetService
  ) { }

  ngAfterViewInit() {
    this.createSheet();
  }

  ngOnDestroy() {
  }

  private createSheet() {
    const sheet = this.sheetService.createSheet(this.device.name);
  }

}

and its service: 及其服务:

export class SheetService {

  public createSheet(name: string) {
    const elementName: string = '#' + name;
    // tslint:disable-next-line: max-line-length
    const tune = 'X:1\nT: Cooley\'s\nM: 4/4\nL: 1/8\nR: reel\nK: Emin\nD2|:"Em"EB{c}BA B2 EB|~B2 AB dBAG|"D"FDAD BDAD|FDAD dAFD|\n"Em"EBBA B2 EB|B2 AB defg|"D"afe^c dBAF|1"Em"DEFD E2 D2:|2"Em"DEFD E2 gf||\n|:"Em"eB B2 efge|eB B2 gedB|"D"A2 FA DAFA|A2 FA defg|\n"Em"eB B2 eBgB|eB B2 defg|"D"afe^c dBAF|1"Em"DEFD E2 gf:|2"Em"DEFD E4|]\n';
    const sheet = abcjs.renderAbc(elementName, tune, {});
    console.log('Created a sheet for ' + name);
    return sheet;
  }

}

The console log shows the sheet is being created: 控制台日志显示正在创建工作表:

Created a sheet for VMPKOutput

and the Chrome browser console element tab shows: Chrome浏览器控制台元素标签显示:

<midi-sheet _ngcontent-hvr-c2="" _nghost-hvr-c4="" ng-reflect-device="[object Object]"><div _ngcontent-hvr-c4="" id="MidiThroughPort-0"></div></midi-sheet>

But there is no visible sheet in the page. 但页面中没有可见的表格。

I don't have a sample using Angular, but here is an example with Vue: https://github.com/paulrosen/vue-abcjs-basic-demo/blob/master/src/components/HelloWorld.vue 我没有使用Angular的示例,但这是Vue的示例: https//github.com/paulrosen/vue-abcjs-basic-demo/blob/master/src/components/HelloWorld.vue

It looks very similar to what you're doing. 它看起来与你正在做的非常相似。

The first thing I notice is that you shouldn't have the '#' in the element id that you are passing in. Perhaps that's it. 我注意到的第一件事是你不应该在你传入的元素id中有'#'。也许就是这样。 So const elementName: string = name; 所以const elementName: string = name;

Here's what I would debug: 这是我要调试的内容:

1) At the time that abcjs.renderAbc(elementName, tune, {}); 1)当时abcjs.renderAbc(elementName, tune, {}); is called, is there a visible element with the id elementName ? 之称,是有id为一个可见元素elementName

2) Look at the value of sheet that is returned. 2)查看返回的工作sheet的值。 It should be an array with one item. 它应该是一个包含一个项目的数组。 There should be reasonable data in it. 应该有合理的数据。 For instance, sheet[0].lines[0].staff[0].voices[0] should return an array of notes. 例如, sheet[0].lines[0].staff[0].voices[0]应该返回一个音符数组。

I've never used this library before, but I took a quick look at the source code and I think you can just pass the native element directly. 我之前从未使用过这个库,但我快速查看了源代码,我认为你可以直接传递本机元素。 Which would make it easier to create multiple components on the same page without having to generate unique IDs. 这样可以更轻松地在同一页面上创建多个组件,而无需生成唯一ID。

The render function is here: 渲染功能在这里:

https://github.com/paulrosen/abcjs/blob/master/src/api/abc_tunebook_svg.js#L160 https://github.com/paulrosen/abcjs/blob/master/src/api/abc_tunebook_svg.js#L160

Tunebook assumes it's a DOM element unless the value is a string: Tunebook假设它是一个DOM元素,除非该值是一个字符串:

https://github.com/paulrosen/abcjs/blob/master/src/api/abc_tunebook.js#L137 https://github.com/paulrosen/abcjs/blob/master/src/api/abc_tunebook.js#L137

Use the component's element instead. 请改用组件的元素。

@Component({
  selector: 'midi-sheet',
  // drop the template as it's not needed
  styleUrls: ['./sheet.component.css']
})
export class SheetComponent implements OnInit {
  @Input() device: Device;

  constructor(private sheetService: SheetService,
              private el: ElementRef<HTMLElement>) { }

  ngOnInit() {
    // should work inside ngOnInit and pass the DOM element of this component
    this.sheetService.createSheet(this.el);
  }
}

In your service just update to use an element. 在您的服务中,只需更新即可使用元素。

export class SheetService {
  public createSheet(el: ElementRef<HTMLElement>) {
    const tune = 'X:1\nT: Cooley\'s\nM: 4/4\nL: 1/8\nR: reel\nK: Emin\nD2|:"Em"EB{c}BA B2 EB|~B2 AB dBAG|"D"FDAD BDAD|FDAD dAFD|\n"Em"EBBA B2 EB|B2 AB defg|"D"afe^c dBAF|1"Em"DEFD E2 D2:|2"Em"DEFD E2 gf||\n|:"Em"eB B2 efge|eB B2 gedB|"D"A2 FA DAFA|A2 FA defg|\n"Em"eB B2 eBgB|eB B2 defg|"D"afe^c dBAF|1"Em"DEFD E2 gf:|2"Em"DEFD E4|]\n';
    return abcjs.renderAbc(el.nativeElement, tune, {});
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM