Webix。检测何时在面板中移动了面板

时间:2019-07-16 21:39:56

标签: javascript dashboard dom-events webix

背景

在Webix中,我们使用的是经过修改的webix.protoUI视图,我们称之为c-dashboard(扩展了webix.ui.dashboard)。 c-dashboard的目的是允许我们有条件地允许或禁止panel中的各个dashboard对象移动

c-dashboard

webix.protoUI({
    name:"c-dashboard",
    isDragNode:function(target){
        var css = (target.className || "").toString();
        //check for webix header and look up
        if (css.indexOf("panel_drag_icon") != -1)
            return target;
        if (target.parentNode && target != this.$view)
            return this.isDragNode(target.parentNode);
        return false;
    },
    $dragCreate:function(object, e){
        //check for header
        if (!this.isDragNode(e.target)) return false;
        //if ok, call parent logic
        return webix.ui.dashboard.prototype.$dragCreate.apply(this, arguments);
    },
}, webix.ui.dashboard);

由于我们正在从数据库中动态加载panel视图的列表(及其配置),因此我们从一个空的c-dashboard视图开始:

webix.ui({
    id: "dashboardView",
    view:"c-dashboard",
    gridColumns:48,
    gridRows:48,
    cellHeight: 50, 
    cellWidth: 50,
    autoplace: false
})

要用数据库中的面板填充c-dashboard,我们从onChange视图的richselect调用此方法:

let dashboardInit = function(id)  {
    webix.promise.all([
        webix.ajax().get("/api/dashboard/" + id + "/widgets")
    ]).then(function(result)  {
        let widgets = result[0].json();
        for (const widget of widgets)  {
            buildWidget(widget);
        }
    });
};

我们最终使用addView中的c-dashboard构建每个面板:

let buildWidget = function(widget)  {

    let widgetId = "widget_" + widget.id;
    $$("dashboardView").addView({
        view: "panel",
        id: widgetId,
        css: "outerWidgetPanel",
        x: widget.x,
        y: widget.y,
        dx: widget.dx,
        dy: widget.dy,
        resize: true,
        body: {  template: panelTemplate(widgetId)  },
    });

    // here we're loading js modules which contains code to render something interesting the `panel` that was just added.
    // the module also contains code to save the panel conifg and other `panel` meta data back to the database.
    (async () =>  {
        const Module = await import("/src/js/widget/" + widget.type);
        let Widget = Module.default;
        let widgetInstance = new Widget(widget);
        widgets.push({  id: widget.id, widgetInstance  });
    })();
};

上面的每个模块都扩展了小部件:

class Widget  {
    constructor(widget, instance = this)  {
        // code to init widget
        this.render();
    }

    render()  {
        // code to render content inside the webix panel.
    }

    move(x,y)  {
        // ajax PUT call to save new widget position to db.
    }
}

我尝试过的内容

我尝试通过向c-dashboard$drop添加呼叫来扩展$dragDestroy

...
$drop:  function(target, source, event)  {
    let panel = $$(event.path[1].id);

    this.callEvent("onPanelDrop", [panel]);
    return webix.ui.dashboard.prototype.$drop.apply(this, arguments);
}

然后将onPanelDrop事件附加到c-dashboard

$$("dashboardView").attachEvent("onPanelDrop", function()  {
    let id = numpart(panel.config.id);  // strip out text, leaving only id.
    let widget = widgets.find(obj => {  return obj.id === id  }).widgetInstance;
    widget.move(panel.config.x, panel.config.y);
})

问题是(在webix中?)有些边缘情况我不确定如何检测到,从而使$drop中的代码不可靠。具体来说,我通常可以从event.path[1].id获取面板对象,但有时需要使用event.path[2].id或偶尔使用其他偏移量。

问题

在正常情况下,我可以使用onBeforeDragInonAfterDrop来检测移动面板的位置。

但是,使用dashobard扩展webix.protoUI会破坏此功能(至少是我这样做的方式)。相反,这两个事件永远不会触发。

使用dashboard扩展webix.protoUI时,检测移动面板的正确方法是什么? /如何添加功能,以便onBeforeDrag上触发onAfterDropc-dashboard事件?

谢谢。

0 个答案:

没有答案