我在我的Rails 4应用程序中使用EmberJs(1.7.0 beta)和jquery.datatables(1.10)。我有一个功能,使用ember填充列表,并使用数据表加载表。我有一个过滤器功能,用户键入搜索字符串,并且必须刷新表。除了第一次从服务器加载数据外,没有其他服务器交互。
router.js.coffee代码
App.Router.map ->
@resource 'portfolios', ->
@route 'edit', {path: '/:id/edit'}
@route 'show', {path: '/:id'}
索引路径代码
App.PortfoliosIndexRoute = Ember.Route.extend
model: (params) ->
@get('store').findAll 'portfolio'
setupController: (controller, model) ->
controller.set 'data', model
索引控制器代码(我正在使用查询参数:emberjs.com/guides/routing/query-params /)
App.PortfoliosIndexController = Ember.ArrayController.extend(
queryParams: ['search_string']
search_string: null
filteredPortfolios: (->
search_string = @get("search_string")
results = @get('data')
###
the search string is entered in a input box and on submitting the search form the url is modified as below. ember picks up the changes string and filters the records
http://localhost:3000/#/portfolios?search_string=random
###
if search_string
results = results.filter((portfolio) ->
portfolio.get('portfolio_name').toLowerCase().indexOf(search_string.toLowerCase()) > -1
)
results
).property('content', 'search_string')
)
呈现数据的视图
<div class="row">
<h1 class="page-header">Portfolios</h1>
<div class="col-md-12">
{{#if search_string}}
{{view App.DataTableView valueBinding="filteredPortfolios"}}
{{else}}
{{view App.DataTableView valueBinding="data"}}
{{/if}}
</div>
</div>
初始化数据表的视图代码
App.DataTableView = Ember.View.extend
tagName: 'table'
classNames: ['dataTable', 'stripe']
didInsertElement: ->
if this.get('value')
data = this.get('value').getEach('data')
this.$().dataTable
sDom: '<"col-md-12"<"panel panel-default"t>><"col-md-12"p>'
iDisplayLength: 25
sPaginationType: 'simple'
aaData: data
aoColumns: [
{sTitle: 'Id', mData: 'id'},
{
sTitle: 'Portfolio Name'
mData: 'portfolio_name'
mRender: (data, type, full) ->
"<a href='#/portfolios/#{full.id}'>#{data}</a>"
},
{sTitle: 'Related Name', mData: 'acquisition_name'}
]
加载页面时,会显示列表。当我输入搜索查询时,将进行过滤并显示过滤后的数据。当我更改搜索查询时,会进行过滤,但不会呈现过滤后的数据。如果我将搜索查询作为空字符串'/#/ member_credit_portfolios?search_string ='发送,则会再次显示整个列表。
我在每种情况下验证了结果数据,如果我不使用App.DataTableView并只使用nornal ul / li列出数据,数据会被过滤和显示。所以问题确实发生在数据表级别。我该如何解决上述问题? 感谢。
答案 0 :(得分:0)
我正在使用Ember + DataTables,最近也遇到了同样的问题。根本问题是,当你将data
传递给aaData
时,你会失去Ember神奇的双向绑定。这很有道理,对吗?毕竟,DataTables为什么要注意Ember的双向绑定?
我使用的解决方案有点不雅,但完成工作。 DataTables可以通过DOM(即您实际输出完整的<table>
数据和所有HandleBars,然后通过Javascript调用$('#myTable').DataTable()
)来获取其数据(正如您通过传递所做的那样)到aaData
属性)或通过AJAX。请参阅http://www.datatables.net/manual/data#Data-sources。
我发现获得双向绑定的唯一方法是使用DOM。这样,HandleBars总是为我更新我的表数据,而DataTables只会渲染这些更改。
如果必须使用javascript,那么您实际上必须通过检测数据中的更改来手动滚动自己的双向绑定,然后让DataTables手动更新数据。这在理论上很有效,但是我遇到了这样一个问题:从丰富的Ember数据DS.Model
(丰富意味着它具有多层关系)转换为相应的JSON,结果令人惊讶地变得棘手。
所有这些归结为以下选项:
选项1:使用DOM
在Handlebars的<table>
中输出您的数据,然后使用DataTables。
选项2:通过Javascript动态传递数据并手动处理数据更新
您现在所做的事情,除了您必须手动检查数据更新,然后使用DataTables API清除表并更新它,特别注意丰富的JSON对象。考虑在后端编写特殊的API来返回DataTables格式的JSON而不仅仅是Ember Data JSON,显然不是理想的,但更容易管理。
我仍然在我的Ember应用程序中为大型数据集建立DataTables模式,所以我们很想知道你最终如何解决这个问题。
答案 1 :(得分:0)
以下是我从您的问题中理解的内容:
search_string
加载页面,该参数应过滤最初显示的结果,search_string
的内容是什么,您都希望保留数据表的“动态过滤”选项,而不向服务器发送任何进一步的查询。如果这是您想要的行为:
您需要将{{#if search_string}}
块放在把手模板中 - 只需渲染整个表格:
{{view App.DataTableView valueBinding="data"}}
search.search
选项(或oSearch.sSearch
选项的初始值(如果您使用的是1.9风格的API)