我有一个允许管理订单的应用。默认视图是一个拆分视图,左侧是订单,右侧是选定的订单详细信息,如下所示:
/Orders /Orders/:order_id
|-----------| |-------------------------------------|
| | | |
| | | |
| | | |
| | | |
| | | |
| List of | | Selected Item |
| Items | | Details |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
|-----------| |-------------------------------------|
我希望能够在“全屏”模式下编辑订单,以便网址和模板如下所示:
/Orders/:order_id/edit/
|---------------------------------------------------|
| |
| |
| |
| |
| |
| |
| Order Edit Interface |
| |
| |
| |
| |
| |
| |
| |
|---------------------------------------------------|
我的路线目前设置如下:
this.resource('Orders.edit', { path: 'Orders/:order_id/edit' } , function () {
this.route('customer-details');
this.route('vendor-details');
this.route('shipping-details');
}
this.resource('Orders', { path: 'Orders' }, function () {
this.resource('Order', { path: ':order_id' }, function () {
this.route('customer-details');
this.route('vendor-details');
this.route('shipping-details');
}
}
我的订单路线如下:
// Orders Route
App.OrdersRoute = Em.Route.extend({
model: function() {
return this.store.find('order');
},
afterModel: function (orders) {
this.transitionTo('orders.order', orders.get('firstObject') );
}
});
// Order Detail
App.OrdersOrderRoute = Em.Route.extend({
model: function(params) {
return this.store.find('order', params.order);
},
setupController: function (controller, model) {
controller.set('content', model);
}
});
// Order Edit Route
App.OrdersEditRoute = Em.Route.extend({
model: function(params) {
if (typeof params.order_id !== 'undefined') {
this.store.find('order', params.order_id).then(function (order) {
this.controllerFor('orders.edit').set('content', order);
});
} else if (typeof params.order !== 'undefined') {
this.store.find('order', params.order).then(function (order) {
this.controllerFor('orders.edit').set('content', order);
});
}
},
afterModel: function(eo) {
this.transitionTo('orders.edit.customer-details', order);
}
});
// Order Edit - Customer Details Route
App.OrdersEditCustomerDetailsRoute = Em.Route.extend({
model: function() {
try {
var order = this.get('order');
return order;
} catch (e) {
console.log('ERROR: ' + e);
}
},
beforeModel: function() {
this.set('order', this.modelFor('orders.edit'));
},
});
如果我在Orders/:order_id
路线/模板中并点击编辑按钮然后将我发送到Orders/:order_id/edit
并加载了所需的界面和数据,则此设置有效。但是,如果我尝试在浏览器窗口中刷新Orders/:order_id/edit
,则无法加载,我会收到以下错误。当以这种方式访问URL时,我也没有点击Orders/:order_id/edit
路由内设置的任何断点。
Uncaught Error: Assertion Failed: Cannot delegate set('classification', N/A) to the 'content' property of object proxy <Synapse.EngineeringOrdersEditDetailsController:ember1242>: its 'content' is undefined. libs.js:2870
Ember.assert libs.js:2870
EmberObject.extend.setUnknownProperty libs.js:23933
set libs.js:9229
setPath libs.js:9289
set libs.js:9209
trySet libs.js:9306
(anonymous function) libs.js:3416
tryable libs.js:5964
tryFinally libs.js:10524
suspendListener libs.js:5967
_suspendObserver libs.js:8311
Binding._sync libs.js:3415
DeferredActionQueues.invoke libs.js:11346
DeferredActionQueues.flush libs.js:11398
Backburner.end libs.js:10861
Backburner.run libs.js:10916
apply libs.js:10745
run libs.js:9378
runInitialize libs.js:45596
n.Callbacks.j libs.js:2
n.Callbacks.k.fireWith libs.js:2
n.extend.ready libs.js:2
I libs.js:2
TypeError: undefined is not a function
at http://localhost:1337/js/app.js:27936:22
at invokeCallback (http://localhost:1337/js/libs.js:13310:19)
at publish (http://localhost:1337/js/libs.js:12980:9)
at publishFulfillment (http://localhost:1337/js/libs.js:13400:7)
at http://localhost:1337/js/libs.js:18818:9
at DeferredActionQueues.invoke (http://localhost:1337/js/libs.js:11348:18)
at Object.DeferredActionQueues.flush (http://localhost:1337/js/libs.js:11398:15)
at Object.Backburner.end (http://localhost:1337/js/libs.js:10861:27)
at Object.Backburner.run (http://localhost:1337/js/libs.js:10916:20)
at executeTimers (http://localhost:1337/js/libs.js:11241:12) libs.js:6663
logToConsole libs.js:6663
RSVP.onerrorDefault libs.js:49435
__exports__.default.trigger libs.js:12274
Promise._onerror libs.js:12998
publishRejection libs.js:13405
(anonymous function) libs.js:18818
DeferredActionQueues.invoke libs.js:11348
DeferredActionQueues.flush libs.js:11398
Backburner.end libs.js:10861
Backburner.run libs.js:10916
executeTimers libs.js:11241
(anonymous function) libs.js:11231
Uncaught Error: Assertion Failed: TypeError: undefined is not a function libs.js:2870
Ember.assert libs.js:2870
RSVP.onerrorDefault libs.js:49436
__exports__.default.trigger libs.js:12274
Promise._onerror libs.js:12998
publishRejection libs.js:13405
(anonymous function) libs.js:18818
DeferredActionQueues.invoke libs.js:11348
DeferredActionQueues.flush libs.js:11398
Backburner.end libs.js:10861
Backburner.run libs.js:10916
executeTimers libs.js:11241
(anonymous function)
我怀疑它与Orders资源层次结构之外的Orders/order/edit
路由有关,但是我无法让出口很好地播放所需的界面。
TLDR - 如何让Orders/:order_id/edit
从URL slug中正确加载模型?使用Ember 1.6.1和Ember数据夹具适配器
答案 0 :(得分:0)
实现所描述内容的两种方法是
单独的资源进行编辑(如果您已尝试过的话,基本上就行了)
嵌套资源并维护一个属性,模板将根据该属性仅呈现出口部分。
这两种方法的例子,
http://emberjs.jsbin.com/wupiwoculoxi/1/edit
<强> HBS 强>
<script type="text/x-handlebars" id="orders">
{{#unless showOnlyEditDetail}}
orders
<br/>
{{#each order in model}}
{{#link-to "order" order.id}}
{{order.name}}
{{/link-to}}
<br/> <br/>
{{/each}}
{{/unless}}
{{!--the following lines before the outlet are shown on purpose for demonstration reasons, the unless helper in this example can hide anything on this template--}}
<hr/>
<i>the value of showOnlyEditDetail:</i><b>{{showOnlyEditDetail}}</b>
<hr/>
{{outlet}}
</script>
<script type="text/x-handlebars" id="order">
the order
<br/>
<br/>
{{this.id}}
<br/>
<br/>
{{this.name}}
<br/>
<br/>
{{#link-to "orderEdit" this.id }}edit1{{/link-to}}
<i>(separate resource)</i>
<br/>
<br/>
{{#link-to "orderEdit2" this.id }}edit2{{/link-to}}
<i>(nested resource and maintaining property)</i>
</script>
<script type="text/x-handlebars" id="orderEdit">
edit the order
<br/>
{{this.id}}
<br/>
{{this.name}}
<br/>
{{#link-to "order" this.id}}back to the order{{/link-to}}
</script>
<script type="text/x-handlebars" id="orderEdit2">
edit2 the order
<br/>
{{this.id}}
<br/>
{{this.name}}
<br/>
{{#link-to "order" this.id}}back to the order{{/link-to}}
</script>
<强> JS 强>
App = Ember.Application.create();
App.Router.map(function() {
this.resource("orderEdit",{path:"orders/:order_id/edit"}, function(){
});
this.resource('orders', { path: 'orders' }, function () {
this.resource('order', { path: ':order_id' }, function () {
this.route('customer-details');
this.route('vendor-details');
this.route('shipping-details');
});
this.resource("orderEdit2",{path:":order_id/edit2"}, function(){});
});
});
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo("orders");
}
});
var ordersData=[
{id:1,name:"order1"},
{id:2,name:"order2"},
{id:3,name:"order3"}
];
App.OrdersRoute = Ember.Route.extend({
model: function() {
return ordersData;
},
setupController:function(c,m){
c.set("showOnlyEditDetail",false);
this._super(c,m);
}
});
/*if the second approach is used then the controller with the specific property
(i.e. showOnlyEditDetail) must be defined.*/
App.OrdersController=Em.ArrayController.extend({
showOnlyEditDetail:false
});
App.OrderRoute = Ember.Route.extend({
model: function(params) {
return ordersData.findBy("id",parseInt(params.order_id,10));
}
});
App.OrderEditRoute = Ember.Route.extend({
model: function(params) {
return ordersData.findBy("id",parseInt(params.order_id,10));
}
});
App.OrderEdit2Route = Ember.Route.extend({
model: function(params) {
return ordersData.findBy("id",parseInt(params.order_id,10));
},
setupController:function(c,m){
this._super(c,m);
this.controllerFor("orders").set("showOnlyEditDetail",true);
},
actions:{
willTransition:function(){
this.controllerFor("orders").set("showOnlyEditDetail",false);
}
}
});