Самый подробный учебник по bpmn.js во всей сети - панель свойств (Часть 1)

JavaScript
Самый подробный учебник по bpmn.js во всей сети - панель свойств (Часть 1)

предисловие

В: Что такое bpmn.js?

"

bpmn.jsЭто набор инструментов рендеринга BPMN2.0 и средство веб-моделирования, которое позволяет выполнять функцию рисования блок-схем во внешнем интерфейсе.

В: Почему я пишу эту серию учебников? 🤔️

"

Из-за потребностей бизнеса компании его необходимо использовать в проектеbpmn.js, Однако из-заbpmn.jsРазработчики игры зарубежные друзья,поэтому отечественных методических материалов мало и нет подробных документов.Поэтому много способов использования и много ям приходится искать самому.Поразмыслив,решил написать серию учебные материалы об этом. чтобы помочь большеbpmn.jsПользователи или разработчики, которые ищут хороший способ рисовать блок-схемы, в то же время для них это еще и своего рода консолидация.

Поскольку это серия статей, она может часто обновляться.Пожалуйста, простите меня, если вы случайно смахнули его, и это не то, что вам нужно😊.

Не просите похвалы👍 не просите сердца❤️ Я просто надеюсь, что смогу вам немного помочь.

Панель свойств

Все узнают о предыдущемpropertiesПосле содержания у вас должно быть общее представление об атрибутах.

Давайте поговорим об этой главеproperties-panel😄...

На самом деле впереди"Самый подробный учебник по bpmn.js во всей сети - основы"уже упоминал, как использоватьproperties-panel, но он просто научил вас цитировать, не вдаваясь в подробности.Теперь позвольте мне подробно объяснить вам, как его использовать.

Прочитав эту главу, вы узнаете:

  • Properties-panelосновное использование
  • Расширенное использованиеProperties-panel

Основное использование панели свойств

properties-panelПо сутиbpmn.jsРасширение, реализующее BPMN 2.0 Modeler, позволяющее редактировать свойства, связанные с выполнением, с помощью панели «Свойства».

Официальный скриншот:

1. Установкаproperties-panel

В предыдущей статье много контента, который не был представлен четко, в этой главе я представлю его осторожно.

Первый — установить его.

Если вы хотите использовать его, вы должны установить его самостоятельно:

$ npm install --save bpmn-js-properties-panel

Также не забудьте ввести стили в проект:

import 'bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css' // 右边工具栏样式

При использовании необходимоhtmlКод предоставляет метку в качестве своего контейнера:

<div id="js-properties-panel" class="panel"></div>

После этого при построенииBpmnModelerпри его добавлении:

 // 这里引入的是右侧属性栏这个框
import propertiesPanelModule from 'bpmn-js-properties-panel'
// 而这个引入的是右侧属性栏里的内容
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'

const bpmnModeler = new BpmnModeler({
	//添加控制板
  propertiesPanel: {
        parent: '#js-properties-panel'
  },
  additionalModules: [
  	propertiesPanelModule,
  	propertiesProviderModule
  ]
})

в предыдущем посте не понялpropertiesPanelModuleа такжеpropertiesProviderModuleРоль , приводящая к неправильному обращению к левой панели инструментов и правому атрибуту, который теперь находится вИсправил в... извините...

2. Установкаcamunda-bpmn-moddle

Еще один момент, если вы хотите использоватьCamunda BPMДля реализации связанных свойств необходимо также установитьcamunda-bpmn-moddleрасширение:

$ npm install --save camunda-bpmn-moddle

Добавьте это в проект:

 // 右侧属性栏
import propertiesPanelModule from 'bpmn-js-properties-panel'
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'
 // 一个描述的json
import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'

const bpmnModeler = new BpmnModeler({
	//添加控制板
  propertiesPanel: {
  	parent: '#js-properties-panel'
  },
  additionalModules: [
  	propertiesPanelModule,
  	propertiesProviderModule
  ],
  moddleExtensions: {
    //如果要在属性面板中维护camunda:XXX属性,则需要此 
    camunda: camundaModdleDescriptor
  }
})

(Camunda BPMЭто решение для механизма выполнения рабочих процессов и автоматизации рабочих процессов, поэтому я не буду его здесь описывать)

а такжеcamunda-bpmn-moddleФункция состоит в том, чтобы сообщить пользователюcamunda:XXXРасширенные свойства.

Я не могу этого понять, давайте конкретно, например, вы его уже установили и использовали в проектеproperties-panelПосле этого открываем страницу, выбираем узел по желанию (возьмем для примера стартовый узел), там будет четыре вкладки (вкладки), которые позволяют модифицировать свойства, если он у вас не установленcamundaи процитироватьcamundaModdleDescriptorЕсли используются следующие три функции, консоль сообщит об ошибке:

это скажет вамunknown type <camunda:FormData>...

Потому что на самом деле вы смотрите наcamunda-bpmn-moddle/resources/camundaИсходный код обнаружит, что это на самом делеjsonфайл, в котором хранится описание каждого атрибута, позже мы его настроимproperties-panelВам также нужно будет написать такойjsonфайла, вы узнаете позже.

3. Эффект фактического использования

Хорошо... давайте на самом деле использовать их и посмотреть, какой эффект они имеют.

Для удобства просмотра даюbpmnModelerсвязать одинcommandStack.changedсобытие, которое будет обновляться каждый раз при изменении графикаxmlРаспечатай.

(См. раздел о привязке событий)

После этого щелкните начальный узел и измените некоторые свойства.Получается, что измененные вами свойства были обновлены синхронно сxmlнад:

Молодец! Ты что-то придумал?!

Да!И по статьеupdatePropertiesРазве метод не очень похож, все они могут обновлять атрибуты доxmlначальство.

Расширенное использованиеProperties-panel

а такжеpalette, contextPadКак и пользовательский метод,Properties-panelЕго также можно изменить на основе значения по умолчанию, что позволяет добавлять некоторые настраиваемые свойства.

Но официально называетсяProperties Panel Extension, кажется более профессиональным... но это неважно, вы знаете, что это значит.

Официальный здесь также приводит пример:properties-panel-extension

На самом деле я следовал официальному примеру, чтобы изучить, как он используется.

Во-первых, давайте проясним, помните, что мы используем оригиналproperties-panel, введены две вещи?

// 这里引入的是右侧属性栏这个框
import propertiesPanelModule from 'bpmn-js-properties-panel'
// 而这个引入的是右侧属性栏里的内容
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'

additionalModules: [
  propertiesPanelModule,
  propertiesProviderModule
]

Я провел некоторое исследование, и если вы не импортируете первый и импортируете только второй, панель свойств не появится.

И если вы импортируете только первый, а не второй, вы получите ошибку...

Я понимаю, что это значит:

  • ПервыйpropertiesPanelModuleЭто означает поле панели свойств, которое должно сообщить другим, что здесь есть панель свойств;
  • второйpropertiesProviderModuleУказывает содержимое на панели свойств, т. е. щелчок по другомуelementЧто должно отображаться.

Увидев это, у вас есть идеи? Хи-хи😁...

В этом случае нам просто нужно переписатьpropertiesProviderModuleВсе, не вводите официальные (то есть изbpmn-js-properties-panel/lib/provider/camundaвведен), но пользовательскийpropertiesProviderModuleчтобы отображать то, что вы хотите.

1. Предварительная подготовка

properties-panelКонтента может быть слишком много, поэтому я создал еще один проект, чтобы провести тематическое исследование.

В проекте до сих пор используетсяvueЧтобы написать, но на самом деле вы можете понять, пока у вас есть немного основного.

Давайте сначала посмотрим на эффект, который должен быть достигнут:

  • Когда вы щелкаете начальный узел, панель свойств справа имеетGeneralи разрешения две вкладки (вкладки);
  • Разрешения На этой вкладке есть группа под названием Права доступа;
  • Под разрешением на редактирование будет атрибут с именем title, который является полем ввода;
  • Измените информацию о начальном узле, чтобы связать атрибут сxmlсередина

впусти насcomponentsсоздать папкуproperties-panel-extensionПапка здесь используется для размещения содержимого атрибутов, которые мы хотим настроить.

затем вproperties-panel-extensionсоздать новыйdescriptorsа такжеproviderпапка.

  • дескрипторы используются для размещения некоторых описанийjsonдокумент
  • провайдер поместите вкладку, которую вы хотите настроить

из-заGeneralэто вкладка, которая у него уже есть, поэтому мы можем оставить ее в покое, теперь мы хотим настроить“权限”вкладку, так что я вproviderСоздал новый в папкеauthorityПапка, куда мы кладем содержимое наших вкладок...

После операции каталог становится таким:

AuthorityPropertiesProvider.jsЭтот файл для записи权限Из этой вкладки это основной файл, который нам нужно написать.

partsЭта папка предназначена для размещения дочерних элементов в каждой группе, например здесь“标题”, я назвал этоTitleProps.

2. Введение возвращаемого значения поставщика

Если вы чувствуете ослепление, когда видите столько файлов выше, пожалуйста, не паникуйте 😂, это нормальная реакция...

Поэтому, чтобы лучше объяснить позже, я решил представить его первым.providerКак возвращаемое значение соответствует структуре страницы.

На картинке выше 👆 мы видим, что:

  1. каждыйproviderбудет одинtabsмассив (аtabэто вкладка)
  2. каждыйtabбудет одинgroupsмассив (аgroupэто группа)
  3. каждыйgroupбудет кучаprops, это могут быть поля ввода или раскрывающиеся списки.

ОК...Теперь стало легче понять😄...

Так что нам просто нужноAuthorityPropertiesProvider.jsПросто верните такую ​​структуру:

/*-选项卡
  |
  -组
   |
   -属性*/
return [
    { // 选项卡
        id: 'general',
        groups: [] // 组
    },
    { // 选项卡
        id: 'authority',
        groups: [
            { // 组
                id: 'edit-authority', // 组id
                entries: [
                    { // 单个props
                        id: 'title',
                        description : '权限的标题',
                        label : '标题',
                        modelProperty : 'title'
                    }
                ]
            }
        ]
    }
]

3. ПишитеAuthorityPropertiesProvider.jsкод

Порядок написания Я намерен рассказывать об этом слой за слоем сверху вниз.

Итак, давайте посмотримAuthorityPropertiesProvider.jsВ общем, что вернуть.

// AuthorityPropertiesProvider.js

import inherits from 'inherits';
// 引入自带的PropertiesActivator,  因为我们要用到它来处理eventBus
import PropertiesActivator from 'bpmn-js-properties-panel/lib/PropertiesActivator';

export default function AuthorityPropertiesProvider(
    eventBus, bpmnFactory, canvas, // 这里是要用到什么就引入什么
    elementRegistry, translate
) {
    PropertiesActivator.call(this, eventBus);
    
    this.getTabs = function (element) {
        var generalTab = {};
        var authorityTab = {};
        return [
            generalTab,
            authorityTab
        ];
    }
}

inherits(AuthorityPropertiesProvider, PropertiesActivator);

Таким образом, структура очень ясна? 😊

Мы на самом деле собираемся переписать внутреннюю частьgetTabsметод, который возвращает то, что нам нужноtab.

каждыйtabВсе имеют фиксированные свойства:

var authorityTab = {
        id: 'authority',
        label: '权限',
        groups: createAuthorityTabGroups(element)
    };

Вы должны соблюдать приведенные выше правила именования, чтобы написать ha😣...

записыватьcreateAuthorityTabGroupsКод функции

в решимостиtabПосле этого нам нужно сказать, какие группы в нем находятся, в это время мы можем создатьcreateAuthorityTabGroupsфункция для возврата нужной группы.

// AuthorityPropertiesProvider.js

import TitleProps from './parts/TitleProps';

function createAuthorityTabGroups(element) {
    var editAuthorityGroup = {
        id: 'edit-authority',
        label: '编辑权限',
        entries: [] // 属性集合
    }
    // 每个属性都有自己的props方法
    TitleProps(editAuthorityGroup, element);
    // OtherProps1(editAuthorityGroup, element);
    // OtherProps2(editAuthorityGroup, element);
    
    return [
        editAuthorityGroup
    ];
}

Например, выше 👆 я вернул编辑权限группа.

И каждый атрибут помещается в группуentriesпод полем...

Эй, почему ты не видишь это здесьentriesКак насчет добавления свойств в массив?

Но, кажется, естьTitlePropsДа зачем это 🤔?

Похоже, что он используется для добавления свойств...

записыватьTitleProps.jsкод

Да, так как атрибут может использоваться в нескольких местах, я поместил его отдельно и поместил вpartsВ этой папке вы можете постоянно добавлять в нее свойства.

Метод этого свойства немного особенный, он принимает два параметра:

  • группа
  • токelement

Поскольку одно и то же свойство может существовать в разных группах, можно передать группу.

Кроме того, различные суждения могут быть сделаны по типу элемента, поэтому текущий элемент может быть передан.

// /parts/TitleProps.js
import entryFactory from 'bpmn-js-properties-panel/lib/factory/EntryFactory';

import { is } from 'bpmn-js/lib/util/ModelUtil';

export default function(group, element) {
  if (is(element, 'bpmn:StartEvent')) { // 可以在这里做类型判断
    group.entries.push(entryFactory.textField({
      id : 'title',
      description : '权限的标题',
      label : '标题',
      modelProperty : 'title'
    }));
  }
}

А 😺 оказываетсяentriesесть в каждомPropsДобавьте к нему атрибуты 🙈...

существуетpushметод, вы должны указать, какой тип добавитьProps.

главным образом черезentryFactory, например здесь, чтобы вернутьtextТип поля ввода.

Что, если иногда вам нужно больше, чем просто поле ввода 🙈?

Неважно,entryFactoryсам предоставляет вам множество типов.

Ctrl + 左键ПроверитьentryFactory, вы можете найти много типов:

OK...

Пока наш обычайauthorityTabВкладка разрешений готова 😊!

Если вы хотите добавить другие вкладки, просто используйте способ, описанный выше 👆...

записыватьgeneralTabкод

выше 👆权限Вкладки - это часть нашего пользовательского контента, если вы хотите использовать некоторые из официальных.tabА как же атрибуты?

generalTabПросто показать вам, как...

Прежде всего то же самое,generalTabЭто должно выглядеть так:

var generalTab = {
    id: 'general',
    label: 'General',
    groups: createGeneralTabGroups(element, bpmnFactory, canvas, elementRegistry, translate)
};

Мы виделиcreateGeneralTabGroupsКажется, что передается много параметров, потому что мы хотим использовать их в нем, и эти параметры строятсяAuthorityPropertiesProviderПредставлено в функции...

приди и посмотриcreateGeneralTabGroupsКак пишется:

// AuthorityPropertiesProvider.js

import idProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/IdProps';
import nameProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/NameProps';
import processProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/ProcessProps';
import linkProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/LinkProps';
import eventProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/EventProps';
import documentationProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/DocumentationProps';

function createGeneralTabGroups(element, bpmnFactory, canvas, elementRegistry, translate) {

    var generalGroup = {
        id: 'general',
        label: 'General',
        entries: []
    };
    idProps(generalGroup, element, translate);
    nameProps(generalGroup, element, bpmnFactory, canvas, translate);
    processProps(generalGroup, element, translate);

    var detailsGroup = {
        id: 'details',
        label: 'Details',
        entries: []
    };
    linkProps(detailsGroup, element, translate);
    eventProps(detailsGroup, element, bpmnFactory, elementRegistry, translate);

    var documentationGroup = {
        id: 'documentation',
        label: 'Documentation',
        entries: []
    };

    documentationProps(documentationGroup, element, bpmnFactory, translate);

    return [
        generalGroup,
        detailsGroup,
        documentationGroup
    ];
}

существуетgeneral, экспортируются три группы, аPropsобеbpmn-js-properties-panel/lib/provider/bpmn/partsВзято из этой папки...

Точно так же, если вы посмотрите его исходный код, вы также можете найти много другихProps, что тебе нужно, просто возьми и используй [собачья голова].

AuthorityPropertiesProvider.jsполный код

Ну, почему бы вам не опубликовать полный код?

На самом деле, не так много,91Ряд:

import inherits from 'inherits';

import PropertiesActivator from 'bpmn-js-properties-panel/lib/PropertiesActivator';


import idProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/IdProps';
import nameProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/NameProps';
import processProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/ProcessProps';
import linkProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/LinkProps';
import eventProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/EventProps';
import documentationProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/DocumentationProps';

import TitleProps from './parts/TitleProps';

function createGeneralTabGroups(element, bpmnFactory, canvas, elementRegistry, translate) {

    var generalGroup = {
        id: 'general',
        label: 'General',
        entries: []
    };
    idProps(generalGroup, element, translate);
    nameProps(generalGroup, element, bpmnFactory, canvas, translate);
    processProps(generalGroup, element, translate);

    var detailsGroup = {
        id: 'details',
        label: 'Details',
        entries: []
    };
    linkProps(detailsGroup, element, translate);
    eventProps(detailsGroup, element, bpmnFactory, elementRegistry, translate);

    var documentationGroup = {
        id: 'documentation',
        label: 'Documentation',
        entries: []
    };

    documentationProps(documentationGroup, element, bpmnFactory, translate);

    return [
        generalGroup,
        detailsGroup,
        documentationGroup
    ];
}

function createAuthorityTabGroups(element) {
    var editAuthorityGroup = {
        id: 'edit-authority',
        label: '编辑权限',
        entries: []
    }

    // 每个属性都有自己的props方法
    TitleProps(editAuthorityGroup, element);
    // OtherProps1(editAuthorityGroup, element);
    // OtherProps2(editAuthorityGroup, element);

    return [
        editAuthorityGroup
    ];
}

export default function AuthorityPropertiesProvider(
    eventBus, bpmnFactory, canvas, // 这里是要用到什么就引入什么
    elementRegistry, translate
) {
    PropertiesActivator.call(this, eventBus);

    this.getTabs = function(element) {
        var generalTab = {
            id: 'general',
            label: 'General',
            groups: createGeneralTabGroups(element, bpmnFactory, canvas, elementRegistry, translate)
        };

        var authorityTab = {
            id: 'authority',
            label: '权限',
            groups: createAuthorityTabGroups(element)
        };
        return [
            generalTab,
            authorityTab
        ];
    }
}

inherits(AuthorityPropertiesProvider, PropertiesActivator);

После нашего раскола он кажется очень простым и древесным 😊 !

(Правильно, Лин Дянь такой простой и добрый человек, как чистый лист бумаги😳...)

4. Пишитеauthority.jsonкод

ОК... на самом деле, здесь почти конец, но на самом деле предстоит сделать очень важный шаг...

Мы только что называли индивидуальными权限вкладка, там же естьtitleсвойство, а также указывает, что толькоStartEventпоявляется в , то в это время мы должныauthority.jsonнекоторые инструкции в документации.

(Почему он названauthority.json, потому что я добавил вкладку под названием权限, название какое хочешь)

Это выглядит так:

{
    "name": "Authority",
    "prefix": "authority",
    "uri": "http://authority",
    "xml": {
      "tagAlias": "lowerCase"
    },
    "associations": [],
    "types": [
      {
        "name": "LinDaiDaiStartEvent",
        "extends": [
          "bpmn:StartEvent"
        ],
        "properties": [
          {
            "name": "title",
            "isAttr": true,
            "type": "String"
          }
        ]
      }
    ]
  }

В этом файле описания мы определяем новый типLinDaiDaiStartEvent, тип расширяет типbpmn:StartEventи добавить к нему“title”атрибуты как атрибуты.

Примечание️: Необходимо определить расширяемый элемент в дескрипторе. Если вы хотите, чтобы это свойство былоbpmn элементов допустимы, его можно расширитьbpmn:BaseElement

Например 🌰 вот так:

...
{
  "name": "LinDaiDaiStartEvent",
  "extends": [
    "bpmn:BaseElement"
  ],
  ...
}

5. Экспорт и использованиеAuthorityPropertiesProvider

После цикла операций (C + V) я наконец закончил писать большую голову...

Давайте посмотрим, как его использовать...

существует/provider/authorityсоздать папкуindex.jsНа экспорт:

import AuthorityPropertiesProvider from './AuthorityPropertiesProvider';

export default {
  __init__: [ 'propertiesProvider' ],
  propertiesProvider: [ 'type', AuthorityPropertiesProvider ]
};

Выглядит знакомо, ха-ха 😄... иcontextPadчто-то типа...

Для демонстрации я создалproperties-panel-extension.vue, и цитируетbpmn.jsа наш только что написалauthority.

<template>
  <div class="containers" ref="content">
    <div class="canvas" ref="canvas"></div>
    <div id="js-properties-panel" class="panel"></div>
  </div>
</template>
<script>
// 原有的 properties-panel 这个框
import propertiesPanelModule from 'bpmn-js-properties-panel'
// 自定义的 properties-panel内容
import propertiesProviderModule from './properties-panel-extension/provider/authority';
// 引入描述文件
import authorityModdleDescriptor from './properties-panel-extension/descriptors/authority'

...
additionalModules: [
  // 右边的工具栏(固定引入)
  propertiesPanelModule,
  // 自定义右边工作栏的内容
  propertiesProviderModule
],
moddleExtensions: {
  // camunda: camundaModdleDescriptor,
  authority: authorityModdleDescriptor
}
...
</script>

Смотрите здесь, я считаю, что вы правыproperties-panelПолучил новое озарение...

Поздравляю 🎉🎉🎉

Лин Дуан очень доволен...

послесловие

Кодовый адрес вышеупомянутого 👆 корпуса учебника:LinDaiDai/bpmn-vue-properties-panel

оproperties-panelЕсть о чем поговорить, поэтому я разделил его на две части, чтобы написать.

До встречи Нового Года еще несколько дней🧨...У Линь Дуодао есть маленькое желание, которое можно было бы сломать несколько лет назад200фанаты...

Скромный блогер просит внимания онлайн... хахаха😂

(выглядит так грустно)

Наконец, если вы также правыbpmn.jsЕсли вам интересно, вы можете присоединиться к нашей группе обмена bpmn.js👇👇👇, вместе учиться и вместе добиваться успехов.

Подпишитесь на официальный аккаунт Лин Дайдао, выберите «группу bpmn.js» в меню «Другое» 😁

LinDaiDai公众号二维码.jpg
Официальный аккаунт LinDaiDai QR code.jpg

Полный каталог серии можно найти здесь:"Самый подробный учебник по bpmn.js во всей сети"

Рекомендации по сериалу:

"Самый подробный учебник по bpmn.js во всей сети - основы"

"Самый подробный учебный материал по bpmn.js во всей сети - мероприятия"

"Самый подробный учебник по bpmn.js во всей сети - рендерер"

"Самый подробный учебник по bpmn.js во всей сети - contextPad"

"Самый подробный учебный материал по bpmn.js во всей сети - пользовательская палитра"

"Самый подробный учебник по bpmn.js во всей сети - редактирование и удаление узлов"

"Самый подробный учебный материал по bpmn.js во всей сети - компоненты пакета"

"Самый подробный учебный материал по bpmn.js во всей сети - свойства"