路由没有看到URL slug

时间:2014-08-15 18:12:27

标签: ember.js

我有一个允许管理订单的应用。默认视图是一个拆分视图,左侧是订单,右侧是选定的订单详细信息,如下所示:

  /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数据夹具适配器

1 个答案:

答案 0 :(得分:0)

实现所描述内容的两种方法是

  1. 单独的资源进行编辑(如果您已尝试过的话,基本上就行了)

  2. 嵌套资源并维护一个属性,模板将根据该属性仅呈现出口部分。

  3. 这两种方法的例子,

    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);
        }
      }
    });