4

我正在尝试在 Angular 7 应用程序中使用 Blockly,但我无法注入 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;
}

给出与上述相同的错误。

关于我还能尝试什么的任何建议?

4

5 回答 5

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>

角度此时会抛出错误,说它无法识别块状标签。所以需要在模块中使用 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']);
  }
}

我在这里写了一篇文章详细解释了这一点 - 将 Google Blockly 与 Angular 集成

于 2019-07-23T02:28:15.770 回答
2

我的回答没有将 XML 放入模板本身,而是放入一个变量中,该变量在模块中没有 NO_ERRORS_SCHEMA 导入的情况下启用集成。

第 1 步:从 Blockly 网站下载文件,然后查找:

  • blockly_compressed.js
  • blocks_compressed.js
  • en.js (或任何你希望你的 blockly 使用的语言)

    将它们复制并粘贴到 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 });
  }
}

就是这样!

于 2020-06-09T20:55:40.523 回答
1

使用ngx-blockly而不是blocklyngx-blockly 是 blockly 的角端口。

按照 npm 页面中说明的步骤进行操作

npm install ngx-blockly --save

https://www.npmjs.com/package/ngx-blockly

于 2020-07-06T14:25:15.697 回答
1

我假设您使用的是@angular/cli。

演示

第 1 步:分块安装

npm install blockly

第二步: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 中与 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)。

于 2018-10-22T05:00:29.287 回答
0

您应该angular.json首先将其添加到。所以 Angular CLI 可以构建它。

        "scripts": [
          "../blockly.js"
        ]
于 2018-10-22T02:38:06.723 回答