开源可视化页面框架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相关内容,请参考我们其他相关文章,
3、开源CMS Drupal整合可视化构建工具GrapesJS(一)
4、开源可视化页面框架GrapesJS教程(二)- 组件开发
5、可视化页面框架GrapesJS开发教程(三)- 与Drupal CMS整合
6、开源可视化页面框架GrapesJS开发教程(四)- 创建 Block
7、CMS与可视化构建工具GrapesJS整合之动态组件开发(五)