uncaught typeerror:对象函数没有方法'tojson'

时间:2013-07-02 08:23:39

标签: backbone.js marionette

我创建了一个像这样的模型

define(['backbone', 'text_dictionary'], function(Backbone, Text_Dict) {
var IndexPageModel = Backbone.Model.extend({
    defaults:{
        val_btn_gotohomepage : Text_Dict.val_btn_gotohomepage,
        val_btn_gotologinpage : Text_Dict.val_btn_gotologinpage,
        val_btn_gotolistpage : Text_Dict.val_btn_gotolistpage
    }
});
return IndexPageModel;
});

并在我的页面代码中使用'new'实例化此模型,如下所示

define([ 'page_layout', 
     'panel_itemview',
     'header_itemview', 
     'content_itemview', 
     'footer_itemview',
     'templates',
     'text_dictionary',
     'indexpage_model',
     'indexpage_logic'], 
    function( Page,
              Panel,
              Header,
              Content,
              Footer,
              Templates,
              Text_Dict,
              IndexPageModel,
              IndexPage_BusnLogic) {
console.log("Success..Inside Index Page.");
var Page_Index = {};
Page_Index.page = (function(){
    var _pageName = Text_Dict.indexpage_name;
    var _pageModel = new IndexPageModel();
    return _pageLayout = Page.pageLayout({
        name:_pageName,
        panelView:      Panel.panelView({name:_pageName, pagetemplate: Templates.simple_panel}),
        headerView:     Header.headerView({name:_pageName, title: Text_Dict.indexpage_header, pagetemplate: Templates.header_with_buttons}),
        contentView:    Content.contentView({name:_pageName, page_model:_pageModel, pagetemplate:Templates.content_index, busn_logic:IndexPage_BusnLogic.HandleEvents}),
        footerView:     Footer.footerView({name:_pageName, title: Text_Dict.indexpage_footer, pagetemplate: Templates.simple_footer})
    });
})();

return Page_Index;
});

我的页面使用页面布局

创建
define([ 'underscore', 'marionette' ], function( _, Marionette ) {
console.log("Success..Inside Index View.");
var Page = {};
var _ReplaceWithRegion = Marionette.Region.extend({
     open: function(view){
        //Need this to keep Panel/Header/Content/Footer at the same level for panel to work properly
        this.$el.replaceWith(view.el);
    }
});
Page.pageLayout = function (opts) {
    var _opts = _.extend ({ name: 'noname',
                            panelView: null,
                            headerView: null,
                            contentView: null, 
                            footerView: null,                               
                            }, opts);
    return new ( Marionette.Layout.extend({
        tagName: 'section', 
        attributes: function() {
            return {
                'id':           'page_' + _opts.name,
                'data-url':     'page_' + _opts.name,
                'data-role':    'page',
                'data-theme':   'a'
            };
        },
        template: function () { 
            return "<div region_id='panel'/><div region_id='header'/><div region_id='content'/><div region_id='footer'/>";
        },
        regions: {
          panel:    {selector: "[region_id=panel]",     regionType: _ReplaceWithRegion},
          header:   {selector: "[region_id=header]",    regionType: _ReplaceWithRegion},
          content:  {selector: "[region_id=content]",   regionType: _ReplaceWithRegion},
          footer:   {selector: "[region_id=footer]",    regionType: _ReplaceWithRegion},
        },

        initialize: function(){
            $('body').append(this.$el);
            this.render();
        },              
        onRender: function() {
            if (this.options.panelView) {
                this.panel.show (this.options.panelView);
            };
            if (this.options.headerView) {
                this.header.show (this.options.headerView);
            };
            if (this.options.contentView) {
                this.content.show(this.options.contentView);
            };
            if (this.options.footerView) {
                this.footer.show (this.options.footerView);
            };
        },
    }))(_opts);
};
return Page;
});

但是在我的项目视图中,当我像这样传递模型参考时

define([ 'underscore', 'marionette', 'event_dictionary', 'app' ], function(_, 
    Marionette, Event_Dict, App) {
console.log("Success..Inside Content Index View.");
var Content = {};
Content.contentView = function(opts) {
    return new (Marionette.ItemView.extend({
        tagName : 'div',
        attributes : function() {
            console.log('options name==' + opts.name);
            console.log("page model=="+opts.page_model);
            return {
                'region_id' : 'content',
                'id' : 'content_' + opts.name,
                'data-role' : 'content'
            };
        },
        initialize : function() {
            _.bindAll(this, "template");
        },
        template : function() {
            return opts.pagetemplate;
        },
        model : function() {
            return opts.page_model;
        }
    }))(opts);
};
return Content;
});

它给了我错误

Uncaught TypeError: Object function () {
            return opts.page_model;
        } has no method 'toJSON' 

2 个答案:

答案 0 :(得分:3)

视图的model属性不能是函数。 Backbone允许这样做一些事情,如url(通过_.result帮助函数),但不是在这种情况下。将您的观看代码更改为没有model功能,只需在initialize中执行此操作:

initialize: function (options) {
    this.model = this.page_model = options.page_model;
}

更新,因为您不会只是接受我的话,here is the Marionette source几乎肯定是异常堆栈跟踪的顶部。再一次:view.model必须是模型对象而不是函数。解决这个问题,错误就会消失。

答案 1 :(得分:0)

接受的答案是正确的,但是要弄清楚为什么我会出现这个错误需要一些麻烦,所以我提供了我的个人用例的解决方案以防万一它可以帮助其他任何人磕磕绊绊在将来的这个页面上。

我有这个:

app.module 'Widget.Meta', (Meta, app, Backbone, Marionette, $, _) ->

  Meta.metaView = Backbone.Marionette.ItemView.extend
    model: app.Entities.Models.meta
    template: '#meta-template'

......当我应该有这个时:

app.module 'Widget.Meta', (Meta, app, Backbone, Marionette, $, _) ->

  Meta.metaView = Backbone.Marionette.ItemView.extend
    model: new app.Entities.Models.meta()
    template: '#meta-template'

只需实例化 函数定义即可。