我有一个Ember View,它在给定一组列和一个数据源时设置jQuery Datatables。在我的例子中,这个数据源来自Ember Data。
我将它用于管理面板,因此我将列出模型中的一些行,然后我将允许管理员对这些项执行操作。操作可以包括“编辑”链接或“删除”链接等。
现在,我使用Datatable的mRender
功能创建指向相应页面的链接。这工作得很好,但强制浏览器刷新有点烦人。我想改用Ember的link-to
功能。
我试过这样的事情:
Ember.Handlebars.compile('{{#link-to "modelName", ' + full.id + '}}Edit{{/link-to}}');
但是,compile将返回一个javascript函数而不是直接的html文本。任何人都可以给我一些建议或代码片段来帮助实现这个功能吗?
这是一个模仿我当前架构的JSBin:JSBin Example
更新
我在路由器中使用location: 'history'
而不是传统的哈希网址。
答案 0 :(得分:4)
{{link-to}}
帮助器可以在模板中使用,但由于您通过mRender
指定了HTML,因此可以在构建的href和适当的路径中添加主题标签。在这种情况下,将不会刷新页面。
http://emberjs.jsbin.com/uYeXixiw/1/edit
<强> JS 强>
App.Router.map(function() {
this.route('details',{path:'user/:user_id'});
});
var data = [
{ 'id': 1, 'firstName': 'Tom', 'lastName': 'Dale' },
{ 'id': 2, 'firstName': 'Yehuda', 'lastName': 'Katz' },
{ 'id': 3, 'firstName': 'Peter', 'lastName': 'Wagenet' }
];
App.DetailsRoute = Ember.Route.extend({
model:function(params){
return data[params.user_id-1];
}
});
App.IndexRoute = Ember.Route.extend({
setupController: function(controller, model) {
controller.set('model', model);
var columns = [
{ "sClass": "item", "mData": "firstName" },
{ "sClass": "item", "mData": "lastName" },
{ "sClass": "item", "mData": null, "bSearchable": false, "bSortable": false, "mRender": function ( data, type, full ) {
return '<a href="#/user/' + full.id + '/">View Details</a>';
}
}
];
controller.set('columns', columns);
},
model: function() {
return data;
}
});
App.DataTableView = Em.View.extend({
tagName:'table',
columnsBinding: 'controller.columns',
didInsertElement: function() {
var self = this;
var value = this.get('value');
var data = null;
if(value === null || value === undefined) {
console.log('Value is null');
data = [];
} else {
console.log('Got Value: ' + JSON.stringify(value));
data = value;//value.getEach('data'); //for Ember Data
var items = JSON.stringify(data);
}
var columns = this.get('columns');
this.$().dataTable( {
"bJQueryUI": true,
"aaData": data,
"aoColumns": columns,
"sEmptyTable": "Loading data from server"
});
},
onValueChanged: function() {
var self = this;
var value = this.get('value');
var data = null;
if(value === null || value === undefined) {
console.log('Value is null');
data = [];
} else {
console.log('Got Value: ' + JSON.stringify(value));
data = value;//value.getEach('data'); //for Ember Data
}
var columns = this.get('columns');
this.$().dataTable( {
"bJQueryUI": true,
"aaData": data,
"aoColumns": columns,
"sEmptyTable": "Loading data from server"
});
return;
}.observes('value')
});
<强> HBS 强>
<script type="text/x-handlebars">
<h2> Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
{{view App.DataTableView valueBinding="model" columnsBinding="columns"}}
</script>
<script type="text/x-handlebars" data-template-name="details">
<h2>details</h2>
{{controller.firstName}}
<br/>
{{#link-to 'index'}}back{{/link-to}}
</script>
编辑 - 对评论的回复 - 对历史记录位置的支持
我注意到有时需要使用纯js从DOM访问ember
个实体。如果与UI
相关的另一个js框架难以被templating
ember
系统采用,则会发生这种情况。真正有趣的是能够以简单的方式实现这一点,而不会破坏您的系统的良好设计和关注的分离。
因此,在您的情况下,因为无法使用handlebars
助手,例如{{link-to}}
,{{action}}
,对于已经呈现的模板,可以从DOM事件中调用ember实体。
返回传递DOM元素的视图的泛型函数
function getView($el){
return Ember.View.views[$el.closest(".ember-view").attr("id")];
}
在mRender
中用作
....
return '<a href=# onclick="getView($(this)).get(\'controller\').send(\'showDetails\',' + full.id + ')">View Details</a>';
(由于jsbin,路径设置有点奇怪,但你明白了)
同样如jsbin中所述,如果使用<a>
标记,那么转换工作需要preventDefault
(即在视图的didInsertElement
回调中)。
<强> JS 强>
App = Ember.Application.create();
App.Router.reopen({
location: 'history'
});
App.Router.map(function() {
this.route('index', {path: '/UnUdUpO/1' }); //For jsbin
this.route('details',{ path:'/UnUdUpO/1/user/:user_id' });
});
var data = [
{ 'id': 1, 'firstName': 'Tom', 'lastName': 'Dale' },
{ 'id': 2, 'firstName': 'Yehuda', 'lastName': 'Katz' },
{ 'id': 3, 'firstName': 'Peter', 'lastName': 'Wagenet' }
];
function getView($el){
return Ember.View.views[$el.closest(".ember-view").attr("id")];
}
App.DetailsRoute = Ember.Route.extend({
model:function(params){
return data[params.user_id-1];
}
});
App.IndexRoute = Ember.Route.extend({
setupController: function(controller, model) {
controller.set('model', model);
var columns = [
{ "sClass": "item", "mData": "firstName" },
{ "sClass": "item", "mData": "lastName" },
{ "sClass": "item", "mData": null, "bSearchable": false, "bSortable": false, "mRender": function ( data, type, full ) {
//if using an <a> tag element for ember transition, then preventDefault is required
return '<a href=# onclick="getView($(this)).get(\'controller\').send(\'showDetails\',' + full.id + ')">View Details</a>';
/*return '<button onclick="getView($(this)).get(\'controller\').send(\'showDetails\',' + full.id + ')" >details</button>';*/
}
}
];
controller.set('columns', columns);
},
model: function() {
return data;
}
});
App.IndexController = Ember.ArrayController.extend({
actions:{
showDetails:function(userId){
this.transitionToRoute('details',userId);
}
}
});
App.DataTableView = Em.View.extend({
tagName:'table',
columnsBinding: 'controller.columns',
didInsertElement: function() {
var self = this;
var value = this.get('value');
var data = null;
if(value === null || value === undefined) {
console.log('Value is null');
data = [];
} else {
console.log('Got Value: ' + JSON.stringify(value));
data = value;//value.getEach('data'); //for Ember Data
var items = JSON.stringify(data);
}
var columns = this.get('columns');
this.$().dataTable( {
"bJQueryUI": true,
"aaData": data,
"aoColumns": columns,
"sEmptyTable": "Loading data from server"
});
//this line is required for links used to make an ember transition
this.$('a').click(function(e){e.preventDefault();});
},
onValueChanged: function() {
var self = this;
var value = this.get('value');
var data = null;
if(value === null || value === undefined) {
console.log('Value is null');
data = [];
} else {
console.log('Got Value: ' + JSON.stringify(value));
data = value;//value.getEach('data'); //for Ember Data
}
var columns = this.get('columns');
this.$().dataTable( {
"bJQueryUI": true,
"aaData": data,
"aoColumns": columns,
"sEmptyTable": "Loading data from server"
});
return;
}.observes('value')
});
<强> HSB 强>
<script type="text/x-handlebars">
<h2> Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
{{view App.DataTableView valueBinding="model" columnsBinding="columns"}}
</script>
<script type="text/x-handlebars" data-template-name="details">
<h2>details</h2>
{{controller.firstName}}
<br/>
{{#link-to 'index'}}back{{/link-to}}
</script>