2017-08-30 203 views
0

使用RactiveJS,Redux和Gridstack製作應用程序。添加新小部件後無法移動Gridstack小部件

當新的小部件被添加時,一切正常,小部件也可移動/可調整大小。但是,當我刪除所有小部件並添加,例如,兩個新的,然後:

  1. 部件無法移動,無法調整大小。如圖:
  2. 當試圖刪除它的小部件消失,但其他小部件改變他們的位置。

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

有幾個問題有:

  • detach unrendering組件時不叫。只有在調用時纔會調用它。您的網格不知道該小部件的刪除。在Ractive將這些小部件元素解除封閉之後,這會導致網格出現怪異現象。

  • 另一方面,grid.removeWidget()從DOM中刪除小部件。狀態改變之後,Ractive仍會嘗試放棄。但由於元素不再存在,並且由於Ractive不知道小部件的移除,它將導致雙重移除。

  • 狀態更改後,小部件的數據不再存在。 id已經是undefined。當您處理teardownunrenderdestruct事件時,您不能再使用id。您必須提前斷開小部件與網格的連接,最好在狀態更改前斷開。

理想情況下,你應該讓Ractive做元素的渲染/ unrendering,只告知gridstack有關使/從電網斷開連接部件。您已使用makeWidget而不是addWidget來渲染。對於刪除,你只需要做同樣的事情。 removeWidget接受第二個參數,如果false將從網格中取消關聯小部件但不從DOM中移除該元素。這在狀態改變之後不會讓Ractive失望。

下面是一個例子:https://jsfiddle.net/fm133mk6/

+0

謝謝您的回答!但是你提供的小提琴,有其他問題:)我添加了三個小工具,移動它們(有些問題也移動了),然後嘗試刪除它們 - 首先刪除成功,但其他人沒有。你能檢查你的小提琴嗎? – Orbitum