添加新窗口小部件后,无法移动Gridstack窗口小部件

时间:2017-08-30 14:51:47

标签: javascript redux nvd3.js ractivejs gridstack

使用RactiveJS,Redux和Gridstack进行的应用程序。

添加新窗口小部件时,一切正常,窗口小部件也可移动/调整大小。但是当我删除所有小部件并添加例如两个新小部件时,则:

  1. 小部件无法移动且无法调整大小。如图:
  2. 当尝试删除小部件时,它会消失,但其他小部件会改变它们的位置。
  3. You can see that right widget is moved to the right side, but handle stays where it is

    jsFiddle is provided as follows

    您可以看到右侧窗口小部件移动到右侧,但句柄保持原样。那么为什么会出现这种行为以及如何处理

    RactiveJS应用程序有三个组件

    DashboardComponent
    WidgetGridComponent
    WidgetComponent
    

    代码如下:

    var Widget = Ractive.extend({
        isolated: false, // To pass events to WidgetGrid component (makeWidget, removeWidget, etc.)
        template: '#widgetTemplate',
        components: {},
        oninit: function() {
            // Load data to widget
        },
        oncomplete: function() {
            this.drawChart();
        },
    
        drawChart: function() {
            var self = this;
    
            function exampleData() {
                return [{
                        "label": "One",
                        "value": 29.765957771107
                    },
                    {
                        "label": "Two",
                        "value": 0
                    },
                    {
                        "label": "Three",
                        "value": 32.807804682612
                    },
                    {
                        "label": "Four",
                        "value": 196.45946739256
                    },
                    {
                        "label": "Five",
                        "value": 0.19434030906893
                    },
                    {
                        "label": "Six",
                        "value": 98.079782601442
                    },
                    {
                        "label": "Seven",
                        "value": 13.925743130903
                    },
                    {
                        "label": "Eight",
                        "value": 5.1387322875705
                    }
                ];
            }
            nv.addGraph(function() {
                var chart = nv.models.pieChart()
                    .x(function(d) {
                        return d.label
                    })
                    .y(function(d) {
                        return d.value
                    })
                    .showLabels(true);
    
                d3.select("#widget" + self.get("id") + " svg")
                    .datum(exampleData())
                    .transition().duration(350)
                    .call(chart);
    
                return chart;
            });
    
        },
    
        data: function() {
            return {
                id: null,
                x: null,
                y: null,
                width: null,
                height: null,
            }
        }
    });
    
    var WidgetGrid = Ractive.extend({
        // isolated:false,
        // twoway:false,
    
        template: '#widgetGridTemplate',
        components: {
            Widget: Widget,
        },
        onrender: function() {
            // Init gridstack instance
            this.bindGridstack();
        },
    
        deleteWidget: function(id) {
            Action.deleteWidget(id);
        },
    
        removeWidget: function(id) {
            $(".grid-stack").data("gridstack").removeWidget("#widget" + id);
        },
    
        createWidget: function(id) {
            $(".grid-stack").data("gridstack").makeWidget("#widget" + id);
        },
    
        updateWidgetSize: function(id, width, height) {
            Action.updateWidgetSize(id, width, height);
        },
        updateWidgetPosition: function(id, x, y) {
            Action.updateWidgetPosition(id, x, y);
        },
    
        bindGridstack: function() {
            var self = this;
            var options = {
                animate: true,
                auto: false, // if false gridstack will not initialize existing items (default: true)
                float: true, // enable floating widgets (default: false)
                disableOneColumnMode: true,
                width: 10, //  amount of columns (default: 12)
                height: 10, // maximum rows amount. Default is 0 which means no maximum rows
                // height: 10,
                // cellHeight: 80,
                disableResize: false,
                disableDrag: false,
                verticalMargin: 0,
                resizable: {
                    handles: 'se'
                }
            };
            var grid = $(".grid-stack").gridstack(options);
    
            // On user ends resizing
            grid.on('gsresizestop', function(event, elem) {
                var $el = $(elem);
                var node = $el.data('_gridstack_node');
                var id = node.el.attr("id").replace("widget", "");
    
                self.updateWidgetSize(id, node.width, node.height, node.el.css("width"), node.el.css("height"));
            });
    
            // On user ends dragging
            grid.on('dragstop', function(event, ui) {
                var $el = $(event.target);
                var node = $el.data('_gridstack_node');
                var id = $el.attr("id").replace("ar-widget", "");
    
                self.updateWidgetPosition(id, node.x, node.y);
            });
        },
    
        data: function() {
            return {
                widgets: [],
            }
        }
    });
    
    var Dashboard = Ractive.extend({
        el: '#dashboard', //document.body,
        template: '#dashboardTemplate',
        isolated: true,
        append: false,
        oninit: function() {
            this.on("add", function() {
                Action.addWidget()
            });
        },
        components: {
            WidgetGrid: WidgetGrid,
        },
        data: function() {
            return {
                store: {}
            }
        }
    });
    

1 个答案:

答案 0 :(得分:1)

那里有几个问题:

    取消组件时,不会调用
  • detach。它仅在调用ractive.detach()时调用。您的网格不知道小部件的删除。在Ractive取消渲染小部件元素之后,这导致网格表现得很奇怪。

  • 另一方面,grid.removeWidget()从DOM中删除小部件。状态改变后,Ractive仍将尝试撤消。但由于元素不再存在,并且因为Ractive不知道小部件的移除,它将导致双重删除。

  • 状态更改后,窗口小部件的数据不再存在。 id已经undefined。处理idteardownunrender事件时,您无法再使用destruct。您必须提前断开小部件与网格的连接,最好是在状态更改之前。

理想情况下,您应该让Ractive执行元素的呈现/取消,并仅通知gridstack关于从网格中创建/断开小部件。您已使用makeWidget代替addWidget在渲染时执行此操作。要删除,您只需要做同样的事情。 removeWidget接受第二个参数,如果false,则会将小部件与网格解除关联,但不会从DOM中删除该元素。在状态改变之后,这会让Ractive感到不知所措。

以下是一个例子:https://jsfiddle.net/fm133mk6/