如何在Ember中使用jsTree插件

时间:2014-06-19 06:39:03

标签: javascript jquery ember.js jstree

我使用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: {} 
});

JSBIN Demo

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

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

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

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

我在这里反对Ember公约。

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

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

或者Ember中是否有任何类似jsTree的组件可以渲染大量具有上下文菜单,拖动和放大等所有功能的树节点。 drop,search,unique plugin,checkbox,lazy loading,update nodes?

1 个答案:

答案 0 :(得分:2)

回答您的问题。

  1. 我正朝着正确的方向前进吗?。您可以更好地模块化代码。
  2. 有没有其他方法可以将jsTree与Ember一起使用?。我不知道你有什么想法,但你必须把jQuery界面包装好。
  3. 是否有像jsTree这样的Ember扩展名?。请查看ember-cli-jstreeember-cli-tree
  4. 详细回复

    我们在生产应用程序中使用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
        }
    });