如何在Ember中使用jsTree插件

Jee*_*evi 40 javascript jquery jstree ember.js

我使用jsTree插件在我的产品中渲染大量的树节点.

现在我正在迁移到Ember,需要在Ember中实现jsTree插件.

我写了一个Ember组件来使用jsTree渲染我的文件夹结构.

我的组件:

<script type="text/x-handlebars" data-template-name="components/temp-tree">
    <div id="treediv">Tree Data</div>
</script>

App.TempTreeComponent = Ember.Component.extend({
    didInsertElement: function(){
        var self = this;
        self.$().jstree({
            'plugins':["contextmenu", "dnd"],
            'core' : {
                'data' : [
                    'Simple root node',
                    { 
                        'text' : 'Root node 2',
                        'state' : {
                            'opened' : true,
                            'selected' : true
                        },
                        'children' : [
                            {'text' : 'Child 1'},
                            'Child 2'
                        ]
                    } 
                ], 
                'check_callback': true
            }
        })
        .on('rename_node.jstree', function(e, data) {
            alert('rename');
        })
        .on('delete_node.jstree', function(e, data) {
            alert('delete');
        });
    }, 
    actions: {} 
});
Run Code Online (Sandbox Code Playgroud)

JSBIN 演示

在我的组件中,对于在树上完成的每个操作,jsTree触发与事件相对应的事件.

我曾经听过事件并在必要时采取必要的行动.

基本上jsTree更新DOM并触发事件.

但是在Ember中我们不会更新DOM,而是需要更新底层MODEL,并且通过双向数据绑定,DOM由Ember更新.

在这里,我反对Ember公约.

我正朝着正确的方向前进吗?

还有其他方法可以将jsTree与Ember一起使用吗?

或者Ember中是否有任何类似jsTree的组件可以渲染大量具有上下文菜单,拖放,搜索,唯一插件,复选框,延迟加载,更新节点等功能的树节点?

Aji*_*kya 2

回答您的问题。

  1. 我的方向正确吗?。您可以更好地模块化您的代码。
  2. 还有其他方法可以将 jsTree 与 Ember 一起使用吗?。我不知道你在想什么,但你必须将 jQuery 接口包装在某些东西中。
  3. 有没有像 jsTree 这样的 Ember 扩展?。查看ember-cli-jstreeember-cli-tree

详细回复

我们在生产应用程序中使用 Ember,我们必须扩展一些 jQuery 插件,我将概述我们的做法。

插件的生命周期分为三个阶段:使用一些选项进行初始化、用户交互触发事件以及事件处理程序操作状态。目标是遵循 Ember 约定在这些阶段上创建一个抽象层。抽象不得使插件文档变得不可用。

App.PluginComponent = Em.Component.extend({
    /***** initialization *****/
    op1: null,
    //default value
    op2: true,
    listOfAllOptions: ['op1', 'op2'],
    setupOptions: function() {
        //setup observers for options in `listOfAllOptions`
    }.on('init'),
    options: function() {
        //get keys from `listOfAllOptions` and values from current object
        //and translate them
        //to the key value pairs as used to initialize the plugin
    }.property(),

    /***** event handler setup *****/
    pluginEvents: ['show', 'hide', 'change'],
    onShow: function() {
        //callback for `show` event
    },
    setupEvents: function() {
        //get event names from `pluginEvents`
        //and setup callbacks
        //we use `'on' + Em.String.capitalize(eventName)`
        //as a convention for callback names
    }.on('init'),

    /***** initialization *****/
    onHide: function() {
        //change the data
        //so that users of this component can add observers
        //and computed properties on it
    }
});
Run Code Online (Sandbox Code Playgroud)