如何在 Angular 应用程序中显示简单的 abcjs sheet?
How to display a simple abcjs sheet in an Angular application?
在 Angular 7
应用程序中使用 abcjs 库,我有以下模板:
<div id="{{device.name}}"></div>
使用控制器:
@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);
}
}
及其服务:
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;
}
}
控制台日志显示正在创建 sheet:
Created a sheet for VMPKOutput
并且 Chrome 浏览器控制台元素选项卡显示:
<midi-sheet _ngcontent-hvr-c2="" _nghost-hvr-c4="" ng-reflect-device="[object Object]"><div _ngcontent-hvr-c4="" id="MidiThroughPort-0"></div></midi-sheet>
但是页面中没有可见的sheet。
我没有使用 Angular 的示例,但这里有一个 Vue 示例:https://github.com/paulrosen/vue-abcjs-basic-demo/blob/master/src/components/HelloWorld.vue
它看起来与您正在做的非常相似。
我注意到的第一件事是,您不应该在传入的元素 ID 中包含“#”。也许就是这样。所以const elementName: string = name;
这是我要调试的内容:
1) 在调用abcjs.renderAbc(elementName, tune, {});
时,是否存在id为elementName
的可见元素?
2) 查看 returned 的 sheet
的值。它应该是一个包含一项的数组。里面应该有合理的数据。例如,sheet[0].lines[0].staff[0].voices[0]
应该 return 一组注释。
我以前从未使用过这个库,但是我快速浏览了源代码,我认为您可以直接传递本机元素。这样可以更轻松地在同一页面上创建多个组件,而无需生成唯一 ID。
渲染函数在这里:
https://github.com/paulrosen/abcjs/blob/master/src/api/abc_tunebook_svg.js#L160
Tunebook 假定它是一个 DOM 元素,除非值是一个字符串:
https://github.com/paulrosen/abcjs/blob/master/src/api/abc_tunebook.js#L137
改用组件的元素。
@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);
}
}
在您的服务中只需更新以使用一个元素。
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, {});
}
}
在 Angular 7
应用程序中使用 abcjs 库,我有以下模板:
<div id="{{device.name}}"></div>
使用控制器:
@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);
}
}
及其服务:
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;
}
}
控制台日志显示正在创建 sheet:
Created a sheet for VMPKOutput
并且 Chrome 浏览器控制台元素选项卡显示:
<midi-sheet _ngcontent-hvr-c2="" _nghost-hvr-c4="" ng-reflect-device="[object Object]"><div _ngcontent-hvr-c4="" id="MidiThroughPort-0"></div></midi-sheet>
但是页面中没有可见的sheet。
我没有使用 Angular 的示例,但这里有一个 Vue 示例:https://github.com/paulrosen/vue-abcjs-basic-demo/blob/master/src/components/HelloWorld.vue
它看起来与您正在做的非常相似。
我注意到的第一件事是,您不应该在传入的元素 ID 中包含“#”。也许就是这样。所以const elementName: string = name;
这是我要调试的内容:
1) 在调用abcjs.renderAbc(elementName, tune, {});
时,是否存在id为elementName
的可见元素?
2) 查看 returned 的 sheet
的值。它应该是一个包含一项的数组。里面应该有合理的数据。例如,sheet[0].lines[0].staff[0].voices[0]
应该 return 一组注释。
我以前从未使用过这个库,但是我快速浏览了源代码,我认为您可以直接传递本机元素。这样可以更轻松地在同一页面上创建多个组件,而无需生成唯一 ID。
渲染函数在这里:
https://github.com/paulrosen/abcjs/blob/master/src/api/abc_tunebook_svg.js#L160
Tunebook 假定它是一个 DOM 元素,除非值是一个字符串:
https://github.com/paulrosen/abcjs/blob/master/src/api/abc_tunebook.js#L137
改用组件的元素。
@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);
}
}
在您的服务中只需更新以使用一个元素。
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, {});
}
}