没有'addArrayObserver'或'removeArrayObserver'

时间:2013-04-02 00:27:28

标签: ember.js ember-data

我正在建模一个有助于管理数据库表的管理界面。有两种型号:[DbxTables,DbxColumns]。我想允许用户使用Boostrap的选项卡菜单选择一个表,然后能够看到该表中的列。这主要是有效的。例如,如果我键入http://my.domain.com/index.html#/performance,其中performance的名称,我会收到以下信息:

performance table

如果我决定通过操纵URL来转到另一个表 - 例如http://my.domain.com/index.html#/food - 那么它将成功切换到右侧窗格中的食物列。当我在左侧标签菜单中使用{{linkTo}}链接时出现问题。发生以下两件事之一:

  1. 如果{{linkTo}}看起来像{{linkTo 'columns' this}},那么它会使网址参数类似于<App.DbxTable:ember371:performance>而不仅仅是performance
  2. 如果{{linkTo}}看起来像{{linkTo 'columns' this.id}}那么它会正确设置ULR参数(或者至少在URL窗口中显示),但如果我点击左侧的“用餐” - 手标签菜单我收到以下错误:对象餐没有方法'addArrayObserver'。如果我点击其他内容,则会显示错误消息“对象餐没有方法'removeArrayObserver'”。
  3. 在上述两种情况下,收到错误后,右侧的列名称不会更新。 {{linkTo}}的第一种风格是Tom Dale的screencast似乎是正确的语法。但是,看到链接关闭,我提出了this.id方法。任何帮助将不胜感激。

    对于一些额外的代码上下文(router.js):

    App.Router.map(function() {
        this.resource('about');
        this.resource('dbx', function() {
            this.resource('columns', { path: ':dbx_table'});
        });
        this.resource('oauth');
        this.resource('postTypeMappings');
    });
    
    App.DbxRoute = Ember.Route.extend({
        model: function() {
            return App.DbxTable.find();
        }
    });
    App.ColumnsRoute = Ember.Route.extend({
        model: function(table) {
            return App.DbxColumn.find(table);
        }
    });
    

    型号:dbx_table.js

    App.DbxTable = DS.Model.extend({
        name: DS.attr("string"),
        desc: DS.attr("string"),
        db_column: DS.attr("string"),
        columns: DS.attr("raw")
    });
    

    型号:dbx_column.js

    App.DbxColumn = DS.Model.extend({
        name: DS.attr("string"),
        dbType: DS.attr("string"),
        insight: DS.attr("string"),
        enum: DS.attr("string"),
        staticUom: DS.attr("string"),
        uomContext: DS.attr("string"),
        jsonStruct: DS.attr("string"),
        desc: DS.attr("string")
    });
    

    型号:store.js

    App.Store = DS.Store.extend({
        revision: 12,
        adapter: DS.RESTAdapter.reopen({
            namespace: 'api/lifegadget'
        })
    });
    
    DS.RESTAdapter.registerTransform('raw', {
        deserialize: function(serialized) {
            return serialized;
        },  
        serialize: function(deserialized) {
            return deserialized;
        }
    });
    

    更新(添加把手):

    为了提供更多细节。以下是把手模板:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset=utf-8 />
    <title>Ember Starter Kit</title>
      <link rel="stylesheet" href="css/normalize.css">
      <link rel="stylesheet" href="css/bootstrap.css">
      <link rel="stylesheet" href="css/style.css">
    </head>
    <body>
    
      <script type="text/x-handlebars">
        <div class="navbar">
          <div class="navbar-inner">
            <a class="brand" href="#">Admin</a>
            <ul class="nav">
                <li>{{#linkTo "dbx"}}DBX{{/linkTo}}</li>
                <li>{{#linkTo "postTypeMappings"}}Post Mappings{{/linkTo}}</li>
                <li>{{#linkTo "oauth"}}OAuth{{/linkTo}}</li>
                <li>{{#linkTo "about"}}About{{/linkTo}}</li>
            </ul>
          </div>
        </div>
        <div id="outlet-target">
        {{outlet}}
        </div>
      </script>
    
      <script type="text/x-handlebars" id="about">
      <div class='about'>
          Admin Screen
      </div>
      </script>
    
      <script type="text/x-handlebars" id="dbx">
      <div class='dbx'>
      <div id="dbx-table-pane" class="tabbable tabs-left">
        <ul class="nav nav-tabs">
            {{#each model}}
                <li>
                    {{#linkTo "columns" this}}{{db_column}}{{/linkTo}}
                </li>
            {{/each}}
            <li id="add-table">
                <a href="#section-add-table" data-toggle="tab"><em>Add DBX Table</em></a>
            </li>       
        </ul>
        <div id="dbx-main" class="tab-content">
        {{outlet}}
        </div
      </div>
    
      </script>
    
      <script type="text/x-handlebars" id="columns">
          The columns are:
          <ul>
            {{#each model}}
            <li>{{name}}</li>
            {{/each}}
          </ul>
      </script> 
    
      <script src="js/libs/jquery-1.9.1.js"></script>
      <script src="js/libs/handlebars-1.0.0-rc.3.js"></script>
      <script src="js/libs/ember-1.0.0-rc.2.js"></script>
      <script src="js/libs/ember-data-12.js"></script>
      <script src="js/app.js"></script>
      <script src="js/router.js"></script>
      <script src="js/models/store.js"></script>
      <script src="js/models/dbx_table.js"></script>
      <script src="js/models/dbx_column.js"></script>
    
    </body>
    </html>
    

    更新2:

    我现在添加了一个演示此问题的简短视频:https://vimeo.com/63388787

1 个答案:

答案 0 :(得分:1)

这与此问题类似:How to show the string value of a non id field for a model in an ember.js route?

我认为您需要使用ColumnsRoute中的serialize hook来定义模型如何转换为网址动态细分。

App.ColumnsRoute = Ember.Route.extend({
    model: function(table) {
        return App.DbxColumn.find(table);
    },
    //dbx_table matches the dynamic route name in your router, and I am assuming
    // you want to use the DbxColumn.name as the URL parameter
    serialize: function(model) {
      return {dbx_table: model.get('name')}; 
    }
});

当直接导航到URL时,model挂钩处理将URL转换为模型对象,并且当路由转换为使用已存在的路径时,serialize挂钩用于构造URL对象,例如使用transitionTo{{#linkTo}}时。