在EmberJS模板上使用DataTables

时间:2014-08-19 21:28:54

标签: javascript ember.js datatable document-ready

我正在尝试在我的EmberJS应用程序中使用Datatables

在常规的jQuery项目中,我总是使用文档就绪事件并在那里启动.datatables();调用。

$(document).ready(function() {
    $('.has-datatable').dataTable();
});

显然,这种方法在Ember应用程序中不起作用。


经过一些互联网搜索后,我发现这个解决方案似乎乍一看似乎有效:

MyEmberApp = Ember.Application.create();

// This would basically run `dataTable();` after
// every view/template rendering.
Ember.View.reopen({
  didInsertElement : function(){
    this._super();
    Ember.run.scheduleOnce('afterRender', this, this.afterRenderEvent);
  },
  afterRenderEvent : function(){
    $('.has-datatable').dataTable();
  }
});

这很有效,datatables插件是针对我的.hbs模板中定义的表运行的,但是有些行/单元格是空的,在控制台中我看到:

  

未捕获错误:无法对不在DOM中的Metamorph执行操作。

如果我禁用此修复并运行模板,我会看到普通的旧表正确填写了我需要的所有数据。

我如何实现我的目标?我只需要在视图渲染(或类似文档的触发器)上运行$('.has-datatable').dataTable();

3 个答案:

答案 0 :(得分:1)

你应该将它包装在Component中。此示例不适用于DataTables,因为我没有使用它,但我将这种方法用于jScrollPanejQuery UI Accordion(并且还将它用于Bootstrap手风琴)。基本方法是:

应用/组件/ jQueryUI的-accordion.js (如果您不使用ember-cli,则可能必须使用不同的位置和/或稍微不同的语法,请参阅下面链接的食谱页。)

import Ember from 'ember';

export default Ember.Component.extend( {
  classNames: 'has-datatable',

  _enableAccordion: function () {
    this.$().accordion({
      animate: 200,
      heightStyle: 'fill',
      icons: false,
    });
  }.on( 'didInsertElement' ),

  _removeAccordion: function () {
    this.$().accordion('destroy');
  }.on( 'willDestroyElement' )
});

应用/模板/组件/ jQueryUI的-accordion.hbs

{{yield}}

要在您的网页中使用它,例如应用/模板/ example.hbs

{{#jqueryui-accordion}}
<span>Content the component displays or works with goes here, inserted where the {{yield}} is</span>
{{/jqueryui-accordion}}

http://emberjs.com/guides/cookbook/helpers_and_components/使用相同的基本原则(这些例子没有ember-cli)。

您正在使用的afterRender事件对我来说是新的,但也可能需要,当然可以与我的示例相结合(我不想用新代码打破它)。

您正在将解决方案应用于每个视图,但这可能是您遇到的问题的一部分:如果存在嵌套的class="has-datatable",则父视图也会在选择器上触发在那里。

答案 1 :(得分:1)

我有组合的jqgrid和ember

尝试以下方法:

myCallback() - js函数

App.MyTable = Ember.View.extend({
     didInsertElement : function() {
            this._super();
            Ember.run.scheduleOnce('afterRender', this, this.didRenderElement);
        },
        didRenderElement : function() {
            this.$().html('<div id="gridWrapper"><table id="list2"></table><div id="gridPager" ></div></div>'
                );
            myCallback(); //inside add your code $('.has-datatable').dataTable();
        }
});

添加到index.html {{view App.MyTable}}:

<script type="text/x-handlebars" id="whatever">

{{view App.MyTable}}
</script>

答案 2 :(得分:0)

我成功地将Datatables v2.1.1集成到Ember 2.11应用程序中。 您需要做的第一件事是从默认的&#39; div&#39;更改组件的标签。到桌子&#39;像这样。

export default Ember.Component.extend({
  tagName: 'table',
  ... <snip> ...
});

在生命周期钩子中创建数据表。

didInsertElement () {
   this._super(...arguments);
   this._createDatatables();
}

_createDatatables() {
   // 1. Create column definitions.
   let columns = ... <snip> ...
   // 2. Create the table.
   let table = this.get('_table');
   if(table) {
      table.destroy();
   }
   // Create a new DataTable and remember it.
   table = this.$().DataTable({
     paging: false,
     scrollY: 600,
     scrollX: true,
     columns : columns
    });
    this.set('_table', table);
}

以这种方式填写表格数据:

 _fillDataTables() {
    let table = this.get('_table');
    let dataArray = this.get('data');
    if(!Ember.isNone(table)) {
      table.rows().remove();
      if(!Ember.isNone(dataArray)) {
        table.rows.add(dataArray);
      }
      table.draw();
    }
  }

最后,如果你向表中添加回调或其他监听器,你最好在willDestroyElement()钩子中清理它。

总结一下,我认为您的代码出错了:

  • 组件的标记名必须是&#39; table&#39;。
  • 使用此方法获取组件的Jquery句柄。$()
  • 您可以使用Ember获得应用程序范围的处理。$
  • 构造函数是DataTable而不是dataTable(大写D),但在以前的版本中可能会出现这种情况。