如何将 gridstack.js 添加到 Ractive.js?

Posted

技术标签:

【中文标题】如何将 gridstack.js 添加到 Ractive.js?【英文标题】:How do I add gridstack.js to Ractive.js? 【发布时间】:2017-05-31 02:01:10 【问题描述】:

我正在使用Ractive.js 和gridstack.js 创建示例应用程序,但不知道如何将gridstack 添加为装饰器。我认为这是将 jQuery 元素添加到 ractive.js 的正确方法,如果不是,请告知。

在我创建装饰器并将其分配给Dashboard 组件后,它实际上不起作用,来自gridstackDecorator 的事件不会缓存在Dashboard 组件中。

我用无效的代码创建了this Fiddle,源代码如下:

Ractive.js 组件树如下所示:

- App
|--- Dashboard    <-- GridstackDecorator
    |--- Widget
        |--- Widget container components
    |--- ...
    |--- Widget
|--- Other components

html 模板如下所示:

<div id="app"></div>

<script>
window.__APP_INITIAL_STATE__ = 
    widgets: [
        id: 1, name: "First widget", x:0, y:0, width:2, height:2,
        id: 2, name: "Second widget", x:5, y:0, width:2, height:2,
        id: 3, name: "Third widget", x:10, y:0, width:2, height:2,
     ],
;
</script>

我尝试分配给仪表板组件的 gridstack 装饰器如下所示:

updateteardown 方法永远不会被调用,这是为什么呢?

var gridstackDecorator = function gridstackDecorator( node, content ) 
    console.log('new decorator', node, content);

    var $gridstack;
    var $gridstackEl;

    var options = 
        cellHeight: 80,
        verticalMargin: 10,
        height:20,
    ;

    $gridstackEl = $(node);
    $gridstackEl.gridstack(options);
    $gridstack = $gridstackEl.data('gridstack');

    $gridstackEl.on('change', function () 
        console.log("change");
        serialize();
    );


    function serialize() 
        var result = _.map($('.grid-stack .grid-stack-item:visible'), function (el) 
            el = $(el);
            var node = el.data('_gridstack_node');
            return 
                id: el.attr('data-custom-id'),
                x: node.x,
                y: node.y,
                width: node.width,
                height: node.height
            ;
        );

        return result;
    


    return 
        update(x,y,z) 
            // NEVER EXECUTES
            console.log("update",x,y,z);
        ,
        teardown(x,y,z) 
                // NEVER EXECUTES
            console.log("teardown",x,y,z);
            $gridstack.destroy();
        
    ;
;

Widget组件,它将渲染每个gridstack容器元素是:

var Widget = Ractive.extend(
    isolated: true,
    template: `<div class="grid-stack-item" data-gs-x="x" data-gs-y="y" data-gs- data-gs->
    <div class="grid-stack-item-content">
        id-name (x: x, y: y)<a href="#" on-click="@this.fire('deleteWidget', event, id)">Xxx</a>
    </div>
</div>`,
    oninit() 
    ,
    onrender() 
        console.log("render");
    ,
    data: 
        x:10,
        y:10,
        width:100,
        height:100,
    
)

仪表板组件,其中gridstack 装饰器分配给:

var Dashboard = Ractive.extend(
    isolated: true,
    components: 
        Widget
    ,
    decorators: 
        gridstack: gridstackDecorator
    ,

    oninit() 
    ,

    deleteWidget(id) 
            console.log("deleteWidget", id);
    ,

    addWidget(name) 
      var widgets = this.get("widgets");
      var id = widgets.length + 1;

      widgets.push(
        id: id,
        name: name,
        x:1,
        y:1,
        width:2,
        htight:2
      );
      this.set("widgets", widgets);
    ,

    updateWidgets(data) 
        console.log("update widgets");
    ,

    template: `
<div class="grid-stack" as-gridstack>
    <a on-click="addWidget('New widget')" href="#">Add New</a>
        #each widgets
        <Widget
                id="this.id"
                name="this.name"
                x="this.x"
                y="this.y"
                
                

                on-deleteWidget="@this.deleteWidget(id)"
        >
        </Widget>
        /each
</div>`
);

使用 Dashboard 组件渲染整个应用程序的根组件如下所示:

var App = new Ractive(
    el: '#app',
    template: `<Dashboard widgets=widgets></Dashboard>`,
    components: 
        Dashboard
    ,
    data: window.__APP_INITIAL_STATE__
);

【问题讨论】:

问题很长,考虑做一个最小的例子 【参考方案1】:

您必须通过在元素中添加“as-$decoratorName”来指示 Ractive 关于您希望调用装饰器的元素,例如,在您的情况下

<div as-gridstack [other attributes...]> ... </div>

您还可以使用命令分隔的列表将参数传递给装饰器的更新函数,例如

<div as-gridstack="arg1, arg2, ..., argN" [other attributes...]> ... </div>

您可以在https://ractive.js.org/v0.x/0.8/decorators 和https://ractive.js.org/v0.x/0.8/writing-decorator-plugins 找到更多信息

【讨论】:

以上是关于如何将 gridstack.js 添加到 Ractive.js?的主要内容,如果未能解决你的问题,请参考以下文章

将 gridstack.js 包装到 Angular 2 组件中

如何在 Angular6 项目中使用 gridstack.js

如何使 Gridstack.js 小部件垂直响应?

gridstack.js 根据内部内容设置 grid-stack-item 高度自动

谷歌地图溢出到外层

gridstack 基础知识,如何使演示工作