我们如何将 Blockly 导入 Angular 7 应用程序?
How do we import Blockly into an Angular 7 application?
我正在尝试在 Angular 7 应用程序中使用 Blockly,但我无法注入 Blockly 编辑器。
我已经从 https://developers.google.com/blockly/guides/get-started/web 下载文件并将 blockly_compressed.js 复制到我的 src 目录(并将其重命名为 blockly.js)。然后我尝试从我的组件访问 Blockly 并收到错误。
我尝试过的:
导入“../blockly.js”
不编译,给出 "error TS2304: Cannot find name '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;
}
给出与上面相同的错误。
关于我还可以尝试什么的任何建议?
您应该先将其添加到 angular.json
。
所以 angular CLI 可以构建它。
"scripts": [
"../blockly.js"
]
我假设您使用的是@angular/cli。
第 1 步:分块安装
npm install blockly
第2步:在architect节点下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 {
}
第四步:创建一个Component,将Blockly声明为any
,并实现AfterViewInit
,这样就可以访问DOM中的blockly相关元素:
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 });
}
}
注意:NPM 中的 Blockly 包是 v1.0,而最新版本是 v1.2。要使用最新版本,只需下载库,将其放在已知目录中,然后修复脚本引用(第 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或者可以在组件TS文件中将工具栏XML表示为字符串,并使用它来进行块注入。
我的组件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']);
}
}
我在这里写了一篇文章对此进行了详细解释 - Integrate Google Blockly with Angular
我的回答没有将 XML 放入模板本身,而是放在一个变量中,该变量无需在模块中导入 NO_ERRORS_SCHEMA 即可实现集成。
第 1 步: 从 Blockly 网站下载文件,然后查找:
- blockly_compressed.js
- blocks_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 });
}
}
就是这样!
使用 ngx-blockly
而不是 blockly
,ngx-blockly 是 angular blockly 的端口。
按照 npm 页面中说明的步骤进行操作
npm install ngx-blockly --save
我正在尝试在 Angular 7 应用程序中使用 Blockly,但我无法注入 Blockly 编辑器。
我已经从 https://developers.google.com/blockly/guides/get-started/web 下载文件并将 blockly_compressed.js 复制到我的 src 目录(并将其重命名为 blockly.js)。然后我尝试从我的组件访问 Blockly 并收到错误。
我尝试过的:
导入“../blockly.js”
不编译,给出 "error TS2304: Cannot find name '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;
}
给出与上面相同的错误。
关于我还可以尝试什么的任何建议?
您应该先将其添加到 angular.json
。
所以 angular CLI 可以构建它。
"scripts": [
"../blockly.js"
]
我假设您使用的是@angular/cli。
第 1 步:分块安装
npm install blockly
第2步:在architect节点下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 {
}
第四步:创建一个Component,将Blockly声明为any
,并实现AfterViewInit
,这样就可以访问DOM中的blockly相关元素:
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 });
}
}
注意:NPM 中的 Blockly 包是 v1.0,而最新版本是 v1.2。要使用最新版本,只需下载库,将其放在已知目录中,然后修复脚本引用(第 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或者可以在组件TS文件中将工具栏XML表示为字符串,并使用它来进行块注入。
我的组件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']);
}
}
我在这里写了一篇文章对此进行了详细解释 - Integrate Google Blockly with Angular
我的回答没有将 XML 放入模板本身,而是放在一个变量中,该变量无需在模块中导入 NO_ERRORS_SCHEMA 即可实现集成。
第 1 步: 从 Blockly 网站下载文件,然后查找:
- blockly_compressed.js
- blocks_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 });
}
}
就是这样!
使用 ngx-blockly
而不是 blockly
,ngx-blockly 是 angular blockly 的端口。
按照 npm 页面中说明的步骤进行操作
npm install ngx-blockly --save