Write up front: Datav is powerful in visual presentation, but weak in user interaction, and can’t handle the needs of product managers. The logic that was originally in the project had to be broken down into many pieces. You need to use native JS or jquery. The underlying implementation of datAV has no quick access. Consult the DATAV staff when you encounter a stuck point. Individuals will not attempt to use such a tool unless it is required by the project.

Key points of use in datAV:

1. Customize components

2. Canvas editor

3. Blueprint editor

4.hook

2. UED:

Iii. Key points of requirement realization:

1. The copy of the button is dynamic, and the interface should be called to obtain it. At most, three buttons are displayed, and more others are received in the drop-down list.

2. When you click a button, request the data of the corresponding button

3. By default, the data corresponding to the first button is displayed

Iv. Custom component implementation:

The file organization structure of the component is shown in Figure 1, where dist is the result of compiling the utils folder locally, and the compiled plug-in is

button-list.ts

import "./button-list.css";
var $ = require("jquery");

type ButtonListProps = {
  config: {
    showMore: Boolean;
    showLength: number;
  };
  data: Record<string, string | number>[];
  firstSelected: any;
  buttonListChange: (val) => void;
};

function render(props: ButtonListProps) {
  const { config, data, firstSelected, buttonListChange } = props;
  const { showMore, showLength } = config;
  let curData = [];
  let selectorData = [];

  if (showMore && showLength) {
    curData = data.slice(0, showLength);
    selectorData = data.slice(showLength);
  } else if (showLength) {
    curData = data.slice(0, showLength);
  } else if (showMore) {
    selectorData = data;
  }

  $("[name=button_list_select]").val(undefined);

  function renderSelect() {
    return `<div class="button_list_select_container" id="button-list-id">
    <select class="button_list_select" name="button_list_select">
    <option></option>
    ${selectorData
      .map((item) => {
        const { label, value } = item;
        return `<option value=${value}>${label}</option>`;
      })
      .join("")}
      </select>
      </div>`;
  }

  function renderButtonList() {
    return `${curData
      .map((item) => {
        const { label, value } = item;
        return `<div class="button ${
          firstSelected === value ? "selected" : ""
        }" data-value=${value}><span class="text">${label}</span></div>`;
      })
      .join("")}`;
  }

  const container = $(`<div class="button_list">
    ${curData.length > 0 ? renderButtonList() : ""}
    ${selectorData.length > 0 ? renderSelect() : ""}
  </div>`);
  return container;
}

export { render };
Copy the code

button-list.less

.button_list { margin-bottom: 10px; display: flex; justify-content: center; font-family: "Microsoft Yahei"; .button { height: 26px; min-width: 77px; Background: rgba(255, 255, 255, 0.13); display: flex; align-items: center; justify-content: center; padding: 0 4px; Color: rgba(255, 255, 255, 0.8); font-size: 16px; line-height: 22px; text-align: center; cursor: pointer; .text { width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } &:not(:last-child) { margin-right: 12px; } &:hover, &. Selected {background-color: rgba(0, 229, 255, 0.4); } } .button_list_select_container { position: relative; .button_list_select { display: none; } // override the 4.0.10 style for select2. Select2-container. Select2-container --default {width: 70px; font-size: 16px; } .select2-container.select2-container--default { font-size: 16px; .select2-results__option[aria-selected="true"] {background-color: rgba(255, 255, 255, 0.13); } &:hover, &. Selected {background-color: rgba(0, 229, 255, 0.4); }. Select2-results__option --highlighted[aria-selected] {background: rgba(0, 229, 255, 0.4); } .select2-search--dropdown { display: none; } .select2-selection--single { border-radius: 0px; Background: rgba(255, 255, 255, 0.13); border: none; .select2-selection__clear { color: #fff; font-size: 2em; }. Select2-selection__rendered {color: rgba(255, 255, 255, 0.8); font-size: 16px; }. Select2-selection__arrow b {border-color: rgba(255, 255, 255, 0.13) transparent transparent; } } .select2-dropdown { border: 0px; background-color: rgba(70, 74, 77); }}. Select2-results__option --selectable {background-color: rgba(255, 255, 255, 0.13); font-size: 16px; Color: rgba(255, 255, 255, 0.8); display: inline-block; width: 100%; &.select2-results__option--selected { background-color: rgba(0, 116, 140, 1); } &.select2-results__option--highlighted { background-color: rgba(0, 116, 140, 1); }}}}Copy the code

index.js

var Event = require("bcore/event"); var $ = require("jquery"); var _ = require("lodash"); // require("select2")($); / / 4.0.10 / / the require (" select2 / dist/CSS/select2. Min. CSS "); var utils = require("./utils/dist/button-list"); Module. Exports = event. extend(function Base(container, config) {this.config = {theme: {},}; this.container = $(container); Apis = config.apis; //hook must have this._data = null; // data this.chart = null; / / chart enclosing init (config); }, { render: function (data, config) { data = this.data(data); var cfg = this.mergeConfig(config); const emitFunc = (val) => { this.emit("value_change", val); }; const eleDom = data.data; const firstSelected = eleDom[0].value; if (eleDom && eleDom.length > 0) { this.emit("button_list_success", "success"); } const app = utils.render({ config: cfg, data: eleDom || {}, firstSelected: firstSelected, buttonListChange: (val) => { emitFunc(val); }}); emitFunc(firstSelected); this.container.html(app); // updateStyle this.updatestyle () if necessary; }});Copy the code

See 6 for the code of hook.js

package.json

{" name ":" @ XXX/button - the list ", "version" : "0.0.33", "dependencies" : {" bcore ":" 0.0.18 ", "jquery" : "2.1.4", "lodash" : "4.6.1"}, "datav" : {" cn_name ":" button component ", "icon" : ""," protocol ": 2," type ": [" regular"], "the view" : {" width ": "400", "height": "200", "minWidth": "200", "minHeight": "100" }, "apis": { "source": { "handler": "Render", "description" : "interface description", "fields" : {" value ": {" description" : "value"}}}}, "config" : {" width ": {" type" : "Text", "name" : "the biggest width button area", "default" : 400}, "height" : {" type ":" text ", "name" : "the maximum height button area", "default" : 26}, "showMore" : {" name ":" whether to show more drop-down ", "type" : "switch", "statusText" : ""," default ": true}," showLength ": {" name" : "Shows the number of the drop-down button", "type" : "stepper", "step" : 1, "min" : 1, the "default" : 3}}, "api_data" : {" source ": {" data" : [{" label ": "1001", "value": "1001" }, { "label": "1002", "value": "1002" }, { "label": "1003", "value": "1003" }, { "label": "1004", "value": "1004" }, { "label": "1005", "value": "1005" }, { "label": "1006", "value": "1006" }, { "label": }}, "button_list_success", "button_list_success", "button_list_success": {"description": "Button data obtained"}}}}Copy the code

Figure 1:

Figure 2:

V. Blueprint Editor configuration:

1. Request data and transform the data into the data structure supported by the button component, and import the data into the button component after data processing (request data needs to use the API data source in the Canvas editor, you can customize a visually invisible component to call the interface)

2. Configure the data source for the button component

Data response results: controlled patterns, static data sources

The received data structure of the button component

3. When the button is clicked, set the callback ID for the API data source to be displayed as a request input parameter

4. Configure the data source for the data to be displayed

Data source type: API

Request method: GET (this dynamic input method, datav currently only supports GET request method)

http://} {API address? BQBM = : BQBM

Vi.HOOK code (at present, the professional version of datAV also has the official website said that only the prime version of HOOK function)

Execution process:

1. Button data should be requested

2. Request the CSS of select2

3. Request select2’s JS

4. Make sure dom.select2() is executed after the DOM is drawn

////////// select2 ///////// /** * @param {Stage} stage */ module.exports = (stage) => { $(document).ready(function () {  console.log("------ready ------ DOM ready!" ); }); // question: why is the following not executed?? // document.addEventListener('DOMContentLoaded', function () { // console.log("------ready ------ DOMContentLoaded!" ); / /}); // const dom = stage.get(" @xxx_button-list_xflui "); // const dom = stage.get(" @xxx_button-list_xflui "); const container = $(dom.container); $(container.find(".button_list_select")).ready(function () { console.log("------ready ------ container -- button_list_select ready!" ); }); $("head").append(' <link href = "Https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel = "stylesheet" / > `); // Method 2: Listen for the callback ID event dom.on("button_list_success", function (data) { if (data === "success") { let script = document.createElement("script"); /* In order for methods in onload to execute, you need to avoid the browser's disk cache. Solution is: when requested js plus random value * / script. The SRC = ` https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js?${+ new Date ()} `; script.onload = function () { console.log("------select2 ------ script.onload!" ); excuteMain(); }; document.head.append(script); }}); function excuteMain() { const select2dom = container.find(".button_list_select").select2({ dropdownParent: Container. find("#button-list-id"), placeholder: "more ", width: 72,}); const emitFunc = (val) => { dom.emit("value_change", val); }; Container. Find (".button"). On ("click", function (e) {const val = $(e.currenttarget).data("value"); container.find(".button").removeClass("selected"); select2dom.val(undefined).trigger("change"); select2dom.siblings(".select2-container").removeClass("selected"); $(e.currentTarget).addClass("selected"); emitFunc(val); }); select2dom.on("change", function (e) { const val = $(e.currentTarget).val(); container.find(".button").removeClass("selected"); select2dom.siblings(".select2-container").addClass("selected"); if (val) { emitFunc(val); }}); }};Copy the code

7. Communication and realization of stuck points (communication process with staff of datAV new group) :

Datav Technician @ Nail Group 21931738:

  • Instead of adding JS dynamically and setting up a global Document object, use NPM
    • The following logical local datav run takes effect, but not after the datav package is introduced into the datav screen
      • $(“head”).append(

        < link href = "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel = "stylesheet" / >

        );

        let script = document.createElement(“script”);

        script.src =

        “Cdn.jsdelivr.net/npm/select2…”;

        document.head.append(script);
  • Q: was the render in index.js executed after the NPM package was loaded? Does the Render method rely on being executed after all the render is done? Render = $(document).ready();
    • A: Any JS tag that is not dynamically appended is executed after the import is complete
    • The $(document).ready() callback calls select2. Dom elements should be fine as long as they have been drawn before select2 is executed
    • 3. Do not manipulate dom outside the container, such as document inside the container
  • Q: How do I fix the problem that the ***.select2() method does not work in the render method? Select2 is executed in the $(document).ready() callback: ***.select2
    • A: This should be for reference only. Dom elements should be fine as long as they are drawn before they are executed
  • Q: A component package upload error occurs
    • A: Check to see if the package defines any dependencies to see if the JS for the network request or DOM element is loaded.
    • A: Wait a few minutes after uploading before adding the package, which takes a while and requires a swipe of the browser
    • A: Drop the version too high and packaging may fail