How do we import Blockly into an Angular 7 application?

后端 未结 5 1545
囚心锁ツ
囚心锁ツ 2021-01-20 17:50

I\'m trying to use Blockly in an Angular 7 application but I\'m unable to inject the Blockly editor.

I have downloaded the files from https://developers.google.com/b

相关标签:
5条回答
  • 2021-01-20 18:23

    My answer does not put the XML into the template itself, but rather in a variable which enable the integration without the NO_ERRORS_SCHEMA import in the module.

    Step 1: Download the files from Blockly website, and look for:

    • blockly_compressed.js
    • blocks_compressed.js
    • en.js (Or any language that you want your blockly to be in)

      Copy and paste them into src/assets/blockly.

    Step 2: In your angular.json file, add the following ( in projects.architect.build.options ):

    "scripts": [
              "src/assets/blockly/blockly_compressed.js",
              "src/assets/blockly/blocks_compressed.js",
              "src/assets/blockly/en.js"
    ]
    

    Step 3: In your 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 });
      }
    }
    

    And that's it !

    0 讨论(0)
  • 2021-01-20 18:35

    Use ngx-blockly instead of blockly , ngx-blockly is angular port of blockly.

    follow the steps explained in npm page

    npm install ngx-blockly --save
    

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

    0 讨论(0)
  • 2021-01-20 18:40

    You should add it to angular.json firstly. So angular CLI can build it.

            "scripts": [
              "../blockly.js"
            ]
    
    0 讨论(0)
  • 2021-01-20 18:40

    I assume you're using @angular/cli.

    Demo

    Step 1: Install blockly

    npm install blockly
    

    Step 2: Add scripts to angular.json under the architect node:

    "scripts": [
       "node_modules/blockly/blockly_compressed.js",
       "node_modules/blockly/blocks_compressed.js",
       "node_modules/blockly/msg/js/en.js"
    ]
    

    Step 3: Add NO_ERRORS_SCHEMA to your AppModule (this is so that you can define custom tags in your components)

    @NgModule({
      imports:      [ BrowserModule, AppRoutingModule ],
      declarations: [ AppComponent ],
      bootstrap:    [ AppComponent ],
      exports: [AppComponent],
      schemas: [NO_ERRORS_SCHEMA]
    })
    export class AppModule {
    }
    

    Step 4: Create a Component, declare Blockly as any, and implement AfterViewInit so that you can access the blockly-related elements in the 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 });
      }
    }
    

    NOTE: The Blockly package in NPM is at v1.0, while the latest version is v1.2. To use the latest, just download the library, put it in a known directory, and fix your script references (Step 2).

    0 讨论(0)
  • 2021-01-20 18:49

    I was able to setup with the config mentioned below -

    install blockly with npm -

    npm install git://github.com/google/blockly.git#1.20190419.0
    

    included below files in scripts section of angular.json file -

        "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"
        ]
    

    added below lines in my component html file -

      <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 will throw error at this point saying it does not recognise the blockly tags. So need to use NO_ERRORS_SCHEMA in the module or can represent the toolbar XML as a string in the component TS file and use it to inject blockly.

    my component TS file -

    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']);
      }
    }
    

    I have written an article explaining this in details here - Integrate Google Blockly with Angular

    0 讨论(0)
提交回复
热议问题