开源可视化页面框架GrapesJS开发教程(四)- 创建 Block

 

本文是介绍可视化页面构建工具 GrapesJS开发教程系列篇之组件介绍,本系列主要是介绍GrapesJS以及与如何对接GrapesJS,如何与CMS整合等相关内容。

如果需要对GrapesJS开发还没有完全了解,可以参考我们之前的相关文章,本篇主要介绍如何在GrapesJS里面创建一个Block。

 

 

 

GrapesJS的组件介绍

 

GrapesJS 的组件是指包含有关元素在画布中如何呈现(由 View 管理)以及其最终代码,所有 Model 属性都会反映在 View 中。GrapesJS 支持添加各种自定义组件,也内置了常用的基础组件,例如区块、文本、图片等。

 

GrapesJS 里开发组件,首先需要弄清楚两个核心概念:Component 和 Block。

Component 定义了一个组件的标签是什么,有什么属性、方法、在Canvas里如何展示,保存为HTML时又应该是什么结果。

Block 可以理解为是一个或多个 Component 组成的“代码片段”。

通常而言,用户在组件库里看到的东西就是Block,在用户将Block拖动到Canvas里之后,Grapes JS会经由解析器将它们转换成Component,这时候用户如果要编辑组件的样式、内容、属性等,就变成和Component交互了。

 

 

GrapesJS的Block构建

 

GrapesJS 的Block主要由BlockManager管理,创建好Block之后,就可以进行拖拽到GrapesJS的界面中来使用和编辑。

1. 创建自定义Block

代码文件是 component.ts,主要是 ngOnInit 触发后的事件,具体代码如下: 

  
  createBlockTemplateConfirmation () {
   const selected = this.editor.getSelected();
   let name = this.blockTemplateForm.get('name')!.value
   let blockId = 'customBlockTemplate_' + name.split(' ').join('_')
   let name_blockId = {
     'name': name,
     'blockId': blockId
   }

   createBlockTemplate(this.editor, selected, name_blockId)
   this.blockTemplateForm.reset();
   this.modalService.getModal('createBlockTemplate').close();
 }
  

createBlockTemplate 方法会调用相关的函数获取component的css和js内容,来看一下 createBlockTemplate的源码,(在index.ts里面)

 

 
 export const getCss = (editor, id) => {
 const style = editor.CssComposer.getRule(`#${id}`);
 const hoverStyle = editor.CssComposer.getRule(`#${id}:hover`);

 if (style){
   if(hoverStyle){
     return style.toCSS() + ' ' + hoverStyle.toCSS()
   }
   return style.toCSS()
 }
 else {
   return ''
 }
}

  export const findComponentStyles = (editor:any,selected:any) => {
   let css =''
   if (selected){
     const childModel =  selected.components().models
     if (childModel) {
       for (const model of childModel) {
         css = css + findComponentStyles(editor,model)
       }
       return css+ getCss(editor, selected.getId());
     }
     else{
       return getCss(editor, selected.getId());
     }
   }
 }
  export const createBlockTemplate = (editor:any, selected:any, name_blockId:any) => {
   const bm = editor.BlockManager
   const blockId = name_blockId.blockId;
   const name = name_blockId.name;
  
   let elementHTML = selected.getEl().outerHTML;
   let first_partHtml = elementHTML.substring(0, elementHTML.indexOf(' '));
   let second_partHtml = elementHTML.substring(elementHTML.indexOf(' ') + 1);
   first_partHtml += ` custom_block_template=true block_id="${blockId}" `
   let finalHtml = first_partHtml + second_partHtml
   const blockCss = findComponentStyles(editor,selected)
   const css = ``
   const elementHtmlCss = finalHtml + css

   bm.add(`customBlockTemplate_${blockId}`,{
     category: 'Custom Blocks',
     attributes: {custom_block_template:true},
     label: `${name}`,
     media: '',
     content: elementHtmlCss,
   })
 }
 

 

创建好Block之后,Block就会出现在GrapesJS的工具栏里面,然后通过拖拽就可以放到页面编辑区了,参考下图

 

2. 给Block添加工具菜单

在每一个Block,当鼠标划上去的时候,就会有一个工具栏,用户可以点击这个工具栏做响应的操作,当然有几个是默认的,比如复制、渲染、删除等,此外,我们也可以自定义工具,比如配置,用户点击后,就弹出一个配置框,在配置框里面,用户可以做各种操作。下面的代码就是注册一个选中事件,来触发工具条。

(我们的动态组件就是用这种方式开发的)

 

   this.editor.on('component:selected', (editor:any) => {
     // whenever a component is selected in the editor
     if (!this.editor) {
       this.editor = editor
     }
     const selectedComponent = this.editor.getSelected();
     if (selectedComponent && selectedComponent.attributes) {
       //createBlockTemplate functionality
       const commandBlockTemplateIcon = 'fad fa-square'
       const commandBlockTemplate = () => {
        // this.modalService.getModal('createBlockTemplate').open(); //Commented for          ………………… now as we have not made Modal yet
       }
        const defaultToolbar = selectedComponent.get('toolbar');
       const commandExists = defaultToolbar.some((item:any) => item.command.name === 'commandBlockTemplate');
        if (!commandExists) {
         selectedComponent.set({
           toolbar: [ ...defaultToolbar, {  attributes: {class: commandBlockTemplateIcon}, command: commandBlockTemplate }]
         });
       }
     }
  });
  

 

具体的效果如下: 

 

然后,我们给工具栏点击增加一个弹出框。

#1. 装一个modal box组件

npm i ngx-smart-modal
ng add @ng-bootstrap/ng-bootstrap

#2. 在component文件里面导入表单

   import {NgxSmartModalService} from 'ngx-smart-modal';
   import {FormBuilder, Validators} from '@angular/forms';
  
下面是Component的源文件
 export class CustomBlockComponent implements OnInit {
 public editor:any = null
 blockTemplateForm = this.formBuilder.group({
   name: ['', Validators.required]
 })
 

Component的HTML文件 :

<ngx-smart-modal #createBlockTemplate (onAnyCloseEvent)="createBlockTemplate.close()" customClass="nsm-centered"
                identifier="createBlockTemplate">
 <div class="modal-header">
   <h4 class="modal-title"> Are you sure you want to save this block template? </h4>
 </div>
 <div class="modal-body">
   <div>This action cannot be undone</div>
 </div>
 <form (ngSubmit)="createBlockTemplateConfirmation()" [formGroup]="blockTemplateForm" >
   <!-- <app-form-errors [errors]="formErrors()"></app-form-errors> -->
   <div class="col-sm-12 form-group mb-3">
     <label for="name">Name</label>
     <input id="name" type="text" class="form-control" formControlName="name"/>
     <!-- <app-field-errors [errors]="fieldErrors('name')"></app-field-errors> -->
   </div>
   <div class="modal-footer">
     <div class="col-sm-12 form-group page-form-controls">
       <button type="submit" [disabled]="!blockTemplateForm.valid" class="btn btn-primary">Save</button>
       <button (click)="createBlockTemplate.close()" class="btn btn-secondary" type="button">Cancel</button>
     </div>
   </div>
 </form>
</ngx-smart-modal>

Component的CSS文件:

/* You can add global styles to this file, and also import other style files */
/* You can add global styles to this file, and also import other style files */
@import "~ngx-smart-modal/ngx-smart-modal.css";

.nsm-dialog.nsm-centered {
 display: grid;
}
.nsm-dialog-lg {
 max-width: 980px;
}
.nsm-dialog-xl {
 max-width: 1200px;
}
.nsm-dialog-xxl {
 max-width: 1500px;
}
.nsm-dialog-full {
 max-width: 100%;
}
   

最终,点击工具栏,得到如下效果,

 

Drupal与GrapesJS的集成演示请点击这里>>

 

更多GrapesJS开发以及Drupal CMS相关内容,请参考我们其他相关文章,

 

1、常见开源可视化低代码页面构建框架对比

2、开源可视化低代码页面构建框架GrapesJS介绍

3、开源CMS Drupal整合可视化构建工具GrapesJS(一)

4、开源可视化页面框架GrapesJS教程(二)- 组件开发

5、可视化页面框架GrapesJS开发教程(三)- 与Drupal CMS整合

6、开源可视化页面框架GrapesJS开发教程(四)- 创建 Block

7、CMS与可视化构建工具GrapesJS整合之动态组件开发(五)

 

8、在线展览和多媒体展示建设方案

9、构建英文网站应该用什么框架?

10、如何基于开源系统构建资料库/文档库平台