Как мы импортируем Blockly в приложение Angular 7?
Я пытаюсь использовать Blockly в приложении Angular 7, но не могу добавить редактор Blockly.
Я скачал файлы с https://developers.google.com/blockly/guides/get-started/web и скопировал blockly_compressed.js в мой каталог src (и переименовал его в blockly.js). Затем я пытаюсь получить доступ к Blockly из моего компонента и получить ошибки.
Что я пробовал:
импорт "../blockly.js"
Не компилируется, выдает "ошибка TS2304: не удается найти имя" Blockly "."
import { Blockly } from '../blockly'
Компилируется, но выдает следующую ошибку при открытии приложения в браузере:
ERROR TypeError: _blockly__WEBPACK_IMPORTED_MODULE_4__.Blockly.inject is not a function
Добавление файла blockly.d.ts со следующим:
export namespace Blockly {
export function inject(div: string, config: any): void;
}
Выдает ту же ошибку, что и выше.
Любые предложения о том, что еще я мог бы попробовать?
2 ответа
Мне удалось настроить конфигурацию, упомянутую ниже -
установить блочно с помощью npm -
npm install git://github.com/google/blockly.git#1.20190419.0
включены ниже файлы в раздел сценариев файла angular.json -
"scripts": [
"node_modules/blockly/blockly_compressed.js",
"node_modules/blockly/blocks_compressed.js",
"node_modules/blockly/msg/js/en.js",
"src/assets/blockly/custom_blocks.js"
]
добавлены строки ниже в моем html файле компонента -
<div id="blocklyDiv" style="width: 100%; height: 100%"></div>
<xml id="toolbox" style="display: none">
<category name="Control" colour="120">
<block type="controls_if"></block>
<block type="controls_repeat_ext" disabled="true"></block>
</category>
<category name="Text" colour="230">
<block type="text"></block>
<block type="text_print"></block>
</category>
<category name="Custom" colour="360">
<block type="begin"></block>
<block type="move"></block>
<block type="end"></block>
</category>
</xml>
angular выдаст ошибку на этом этапе, говоря, что он не распознает блочные теги. Поэтому необходимо использовать NO_ERRORS_SCHEMA в модуле или можно представить XML панели инструментов в виде строки в файле TS компонента и использовать его для блочного внедрения.
мой компонентный файл TS -
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { ProgramService } from '../services/program.service';
import { IProgram } from '../models/program';
declare var Blockly: any;
@Component({
selector: 'app-program-create',
templateUrl: './program-create.component.html',
styleUrls: ['./program-create.component.scss']
})
export class ProgramCreateComponent implements OnInit {
title: string;
programName: string;
program: IProgram;
workspace: any;
constructor(
private route: ActivatedRoute,
private programService: ProgramService,
private router: Router
) {
this.title = 'Create Visual Program';
this.route.params.subscribe(params => {
this.programName = params['programName'];
this.program = this.programService.getOne(this.programName);
if (!this.program) {
this.program = {
name: this.programName,
xmlData: null
};
}
console.log(
'creating/editing the program - ',
JSON.stringify(this.program)
);
});
}
ngOnInit() {
this.workspace = Blockly.inject('blocklyDiv', {
toolbox: document.getElementById('toolbox'),
scrollbars: false
});
if (this.program.xmlData) {
this.workspace.clear();
Blockly.Xml.domToWorkspace(
Blockly.Xml.textToDom(this.program.xmlData),
this.workspace
);
}
}
saveProgram(): void {
this.program.xmlData = Blockly.Xml.domToText(
Blockly.Xml.workspaceToDom(this.workspace)
);
console.log('saving the program - ', JSON.stringify(this.program));
this.programService.upsertOne(this.program);
this.router.navigate(['listProgram']);
}
}
Я написал статью, подробно объясняющую это здесь - Интеграция Google Blockly с Angular
Мой ответ не помещает XML в сам шаблон, а скорее в переменную, которая обеспечивает интеграцию без импорта NO_ERRORS_SCHEMA в модуле.
Шаг 1. Загрузите файлы с веб-сайта Blockly и найдите:
- blockly_compressed.js
- block_compressed.js
en.js (или любой язык, на котором вы хотите, чтобы ваш блок был)
Скопируйте и вставьте их в src / assets / blockly.
Шаг 2. В файле angular.json добавьте следующее (в projects.architect.build.options):
"scripts": [
"src/assets/blockly/blockly_compressed.js",
"src/assets/blockly/blocks_compressed.js",
"src/assets/blockly/en.js"
]
Шаг 3: В вашем component.ts:
import { Component, AfterViewInit } from '@angular/core';
declare var Blockly: any
@Component({
template: `<div id="blocklyDiv" style="height: 480px; width: 600px;"></div>`,
selector: 'app-blockly',
styleUrls: ['./blockly.component.scss']
})
export class BlocklyComponent implements AfterViewInit {
ngAfterViewInit(): void {
const toolbox = `
<xml>
<block type="controls_if"></block>
<block type="controls_whileUntil"></block>
</xml>`;
Blockly.inject('blocklyDiv', { toolbox });
}
}
И это все!
Я предполагаю, что вы используете @angular/cli.
Шаг 1. Установите блочно
npm install blockly
Шаг 2. Добавьте сценарии в angular.json
под узлом архитектора:
"scripts": [
"node_modules/blockly/blockly_compressed.js",
"node_modules/blockly/blocks_compressed.js",
"node_modules/blockly/msg/js/en.js"
]
Шаг 3: Добавить NO_ERRORS_SCHEMA
к вашему AppModule (это так, что вы можете определить пользовательские теги в ваших компонентах)
@NgModule({
imports: [ BrowserModule, AppRoutingModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ],
exports: [AppComponent],
schemas: [NO_ERRORS_SCHEMA]
})
export class AppModule {
}
Шаг 4. Создайте компонент, объявите Blockly как any
и реализовать AfterViewInit
так что вы можете получить доступ к блочно-связанным элементам в DOM:
import { Component, AfterViewInit, ViewChild, ElementRef } from '@angular/core';
declare var Blockly: any;
@Component({
selector: 'app-root',
template: `
<div id="blocklyDiv" style="height: 480px; width: 600px;"></div>
<xml id="toolbox" #toolbox style="display: none">
<block type="controls_if"></block>
<block type="logic_compare"></block>
<block type="controls_repeat_ext"></block>
<block type="math_number"></block>
<block type="math_arithmetic"></block>
<block type="text"></block>
<block type="text_print"></block>
</xml>
`
})
export class AppComponent implements AfterViewInit {
workspace: any;
@ViewChild('toolbox') toolbox: ElementRef;
ngAfterViewInit(): void {
this.workspace = Blockly.inject('blocklyDiv',
{toolbox: this.toolbox.nativeElement });
}
}
ПРИМЕЧАНИЕ. Пакет Blockly в NPM имеет версию v1.0, а последняя версия - v1.2. Чтобы использовать последнюю версию, просто загрузите библиотеку, поместите ее в известный каталог и исправьте ссылки на сценарии (шаг 2).
Использовать ngx-blockly
вместо того blockly
, ngx-blockly - это угловой порт блочного.
следуйте инструкциям на странице npm
npm install ngx-blockly --save
Вы должны добавить его в angular.json
во-первых. Так что угловой CLI может его построить.
"scripts": [
"../blockly.js"
]