0

我是骨干新手。我使用 MVC 创建了一个显示“Hello”的新项目。但是我在这个文件backbone.marionette.js中遇到了错误这个错误

未捕获的类型错误:对象

没有方法'html'

你能帮我消除这个错误吗

<!doctype html>
<html lang="en">
    <head>
        <meta content='width=device-width, initial-scale=1' name='viewport'>


        <!-- PHONEGAP SPECIFIC ITEMS -->
        <script src="bridge/cordova-2.4.0-android.js" type="text/javascript"></script>


        <!-- END PHONEGAP SPECIFIC ITEMS -->

        <!--Library related files -->
        <script src="js/libs/jquery.js" type="text/javascript"></script>
        <script src="js/libs/underscore.js" type="text/javascript"></script>
            <script src="js/libs/backbone.js" type="text/javascript"></script>
        <script src="js/libs/bootstrap.min.js" type="text/javascript"></script>
        <script src="js/libs/jquery.hoverIntent.minified.js"></script>
        <script src="js/libs/jquery-ui.js"></script>
            <script src="js/libs/backbone.marionette.js" type="text/javascript"></script>
        <script src="js/libs/page_controller.js" type="text/javascript"></script>

        <!--library file ends -->

        <script src="js/app-start.js" type="text/javascript"></script>
        <script src="js/app-controller.js" type="text/javascript"></script>
        <script src="js/app.js" type="text/javascript"></script>
        <script src="js/routers/app-router.js" type="text/javascript"></script>

        <script src="js/regions.js" type="text/javascript"></script>

        <script src="js/controllers/CaseFoldersWindow_controller/CaseFoldersWindow.js" type="text/javascript"></script>
        <script src="js/views/CaseFoldersWindow_view/CaseFoldersWindow.js" type="text/javascript"></script>

        <script src="js/controllers/CaseInformation_controller/CaseInformation.js" type="text/javascript"></script>
        <script src="js/views/CaseInformation_view/CaseInformation.js" type="text/javascript"></script>


        <script src="js/libs/basic.js" type="text/javascript"></script>
        <script src="js/libs/jquery.simplemodal.js" type="text/javascript"></script>

    </head>

    <body id='bodyContentRegion'>

    </body>
</html>
-------------------------------------------------------------------
//    Always use this pattern in order to don't override existing objects
         ----------------------------  App.js-----------------------
;(function() {
    window.App = window.App || {};
    _.extend(App, new Backbone.Marionette.Application());
    // Extend the App object organizing the objects needed
    App.pages = App.pages || {};
    App.views = App.views || {};
    App.routers = App.routers || {};
    App.models = App.models || {};
    App.collections = App.collections || {};
    // Regions are defined in regions.js and initialized in App.addInitializer() in this file
    App.regions = App.regions || {};
    // Templates container
    App.templates = App.templates || {};
    //    Temporary settings changing runtime
    App.session = App.session || {};
     App.current_page =  App.current_page || {};
    //keep reference to global database.

    // Page and view prototype objects
    App.Next_SaveButtonStatus=false;

    window.cpd = window.cpd || {};
    cpd.pages = cpd.pages || {};
    cpd.views = cpd.views || {};



    //Custom settings. You can configure custom settings in js/mxf.settings.js
    App.settings = App.settings || {};
    //        Merge defaults and settings
    App.settings = $.extend(true, {}, App.defaults, App.settings);
    //        Remove defaults to free memory
    delete App.defaults;
    //    todo transform the communication object in a proper class with a constructor
    App.communication = window.communication;

    // App initializer
    App.addInitializer(function(options) {
        // todo avoid explicit initialize(), prefer App.controller = new Controller
        //  Add regions to App
        App.regions = App.regions || {};
        _.extend(App.regions, {
            body : new cpd.regions.body(),

        });

        App.controller.initialize();
        // Maybe the main router could be stored in App.mainRouter
        App.routers.mainRouter = new cpd.routers.AppRouter({

            controller : App.controller
        });

        //  These settings should depend on some App.settings parameters
        Backbone.emulateHTTP = true;
        Backbone.emulateJSON = true;
    });
    //Fires just after the initializers have finished
    App.bind('initialize:after', function(options) {
        if (Backbone.history) {
            Backbone.history.start();
        }
    });

    // Not belonging to App
    App.templatePath = 'js/templates/';

    App.templates.load = function(templateId) {


        $.ajax({
            url : App.templatePath + templateId + ".html",
            data : {},
            success : function(data) {
                App.templates[templateId] = data;

            },
            error : function(err) {
                console.log('Error loading Template for: ' + templateId + ".html");
            },
            dataType : 'text'
        });
    }

    Backbone.Marionette.ItemView = Backbone.Marionette.ItemView.extend({
        renderTemplate : function(template, data) {
            return _.template(template, data);
        }
    });

    Backbone.Marionette.TemplateManager.get = function(templateId, callback) {
    console.log("templateId"+templateId.regionTemplate);
        if ($.isPlainObject(templateId)) {
            var templateId_str = templateId.regionTemplate + '_page';
        } else {
            var templateId_str = templateId + '_module';
        }
        //console.log('templateId: ', templateId_str)
        var template = this.templates[templateId_str];
        if (template) {
            callback && callback.call(this, template);
        } else {
            var that = this;
            this.loadTemplate(templateId, function(template) {
                that.templates[templateId_str] = template;
                callback && callback.call(that, template);
            });
        }
    }

    Backbone.Marionette.TemplateManager.loadTemplate = function(templateId, callback) {
        var _this = this;
        //ms = Date.UTC();
        if ($.isPlainObject(templateId)) {
            templateId = templateId.regionTemplate;
        } else {
            templateId = templateId + '.tmpl';
        }
        $.ajax({
            // url: App.templatePath+templateId + ".html?"+ms,
            url : App.templatePath + templateId + ".html",
            data : {},
            success : function(data) {
                App.templates[templateId] = data;
                callback.call(this, data);
            },
            error : function(err) {
                console.log('Error loading Template for: ' + templateId + ".html");
            },
            dataType : 'text'
        });
    }

    App.applyBodyID = function(DOMid) {
        this.$el = this.$el || $('body');
        this.$el.attr('id', DOMid + 'Body');
    }

    Backbone.Marionette.RegionManager = Backbone.Marionette.RegionManager.extend({

        open : function(view) {
            var that = this;
            view.el = this.el;
            view.$el = this.$el;
            view._region = this;
            if (!this.no_loading_anim)
                this.$el.addClass('loading_region');
            $.when(view.render()).then(function() {
                view.onShow && view.onShow();
                that.trigger("view:show", view);
            });
        }
    });
    Backbone.Marionette.CollectionView = Backbone.Marionette.CollectionView.extend({
        dont_store_children : false, //patch to delete all chid views before new render
        keep_collection_spinner_till_empty : false, // force the spinner to stay on till correct values are populated, can also be forced to stay on with correct DIVS, Check with Akrant
        _removed_spinner_on_actual_render : false, // this is not to be called from outsides
        // off to prevent any clashes anywhere
        render : function() {
            this.renderModel();
            this.$el.addClass('loading_region');
            // this.closeChildren(); // do not cache old Child views
            if (this.children && this.dont_store_children) {
                this.closeChildren();
            }
            this.collection.each(this.addChildView);
            if (this.onRender) {
                this.onRender();
            }
            return this;
        },
        addChildView : function(item) {
            var html = this.renderItem(item);
            var _this = this;
            if (this.keep_collection_spinner_till_empty) {
                if (!this._removed_spinner_on_actual_render) {
                    if ( typeof ($(html).children()[0]) == "undefined")// && $(html).hasClass("no_content_loading_region_h"))
                    {
                        //console.log($(html));
                    } else {
                        this._removed_spinner_on_actual_render = true;
                        this.$el.removeClass('loading_region');
                        // console.log($(html));
                    }
                } else {
                    // console.log("COLL: SPINNER WAS REMOVED LAST TIME")
                    this.$el.removeClass('loading_region');
                }
            } else {
                // console.log("COLL: OPTION TO KEEP SPINNER NOT CHOSEN")
                this.$el.removeClass('loading_region');
            }
            this.appendHtml(this.$el, html);
        },
        renderItem : function(item) {
            if (!this.itemView) {
                var err = new Error("An `itemView` must be specified");
                err.name = "NoItemViewError";
                throw err;
            }
            var view = new this.itemView({
                model : item,
                cViewItem : true
            });
            view.render();
            this.storeChild(view);
            return view.el;
        },
        close : function() {
            this.unbind();
            this.unbindAll();
            this.$el.empty();

            this.closeChildren();

            if (this.onClose) {
                this.onClose();
            }
            // this.closeScrolls();
            // this.closeScrollCleanup();
            if (this.manualCleanup) {
                this.manualCleanup()
            }
        },
        closeChildren : function() {
            var _this = this;
            if (this.children) {
                _.each(this.children, function(childView, key) {
                    childView.close();
                    if (_this.dont_store_children)
                        delete _this.children[key];
                });
            }
        },
        scroll : {},
        closeScrolls : function() {
            this.scroll.destroy();
            this.scroll = null;
            console.log("APP JS: Scrolls closed");
        },
        closeScrollCleanup : function() {
            //empty, overload in your own items
        }
    })

    Backbone.Marionette.ItemView = Backbone.Marionette.ItemView.extend({
        removeOnClose : false, // If true, the DOM element get removed when the view close
        keep_spinner_till_empty : false, // force the spinner to stay on till correct values are populated, can also be forced to stay on with correct DIVS, Check with Akrant
        render : function() {

            if (this.keep_spinner_till_empty) {
                this.$el.addClass('loading_region');
                //this.keep_spinner_till_empty = false;
            }

            if (this.model && !this.model_change_bound && this.follow_model_changes) {
                this.model_change_bound = true;
                this.bindTo(this.model, "change", this.render, this);
            }
            var _this = this, data = this.serializeData(), dfd = jQuery.Deferred();

            this.getTemplate(function(template) {

                var html = _this.renderTemplate(template, data);
                _this.$el = $(_this.el);
                if (_this.options.cViewItem) {
                    var $el = $(html).insertBefore(_this.$el);
                    _this.$el.remove();
                    _this.$el = $el;
                    _this.el = _this.$el.first();
                } else if (_this.options.appendToEl) {
                    _this.$el.append(html);
                } else {
                    _this.$el.html(html);
                }
                _this.delegateEvents();
                if (_this.onRender)
                    _this.onRender();
                _this.trigger('view:rendered');
                App.vent.trigger('view:rendered', {
                    view : _this
                });
                //This has been added. Use if you need to agnostically extend or manipulate a view.
                dfd.resolve();
            });

            dfd.done(function() {
                //console.log(_this.$el);
                //console.log(_this.keep_spinner_till_empty);
                if (_this.keep_spinner_till_empty) {
                    _this.keep_spinner_till_empty = false;
                } else {
                    _this.$el.removeClass('loading_region');
                }
                if (_this.ready) {
                    _this.ready();
                    _this.ready_has_been_called = true;
                }
            });
            return dfd.promise();
        },
        close : function() {
            this.unbindAll();
            this.unbind();
            this.$el.empty().unbind();
            //this.remove(); //this was removing tabs on experts/people pages
            if (this.removeOnClose) {
                this.remove();
                this.$el.empty()
                delete this;
            }

            if (this.onClose) {
                this.onClose();
            }

            if (this.manualCleanup) {
                this.manualCleanup()
            }
        }
    });

})();
----------------------------------------------------------------

App-controller.js---------------

window.App = window.App || {};
var time;
// todo make a proper class instead of a simple object
App.controller = {
    initialize : function() {
        //Bind global events here

        //call to close all popups.
        App.addInitializer(function(options) {
            //Bind router event beforeroute
            App.routers.mainRouter.on('beforeroute', App.controller.beforeRoute);
            App.routers.mainRouter.on('onRoute', App.controller.pageHandling);
            //App.routers.mainRouter.on('afterRoute', App.controller.show_header);
        });
        //The event start is triggered after all the initializers
        App.bind('start', function(options) {

        });
    },
    page : function(name) {

        console.log("page call");
        var page = new cpd.pages[name]
        console.log(page);
        console.log(name);


   //  }
        return page;
    },
    //This function get called every time a route is going to change, before the other specific routing functions get called.
    beforeRoute : function(e, args) {
        console.log("beforeRoute**********************");
        //Close all the not permanent regions
        console.log("beforeRoute call")
        for (r in App.regions) {
            var region = App.regions[r];
            if (!region.permanent) {
                region.close();
            }
        }


        //if(name=="words"||name=="home"){


        App.session.params = App.session.params || {};
        App.session.params.route = {}
        //App.vent.trigger("page:load");
    },

    pageHandling : function(route, linkedCall, params) {
        console.log("SEE THIS");
        if (App.current_page)// Save current Page in Tracking TODO: we may need to save options to know which tab user is on
        {
            //Read only variables throughout the application. DO NOT EDIT/TOUCH
            App.current_page.page = linkedCall;
            //App.current_page.params = params;
            //App.current_page.route = route;
        }

    },

    // ---- Routes ----
    CaseFoldersWindow : function() {

        App.regions.body.show(App.controller.page('CaseInformation'));
    },


};
---------------------------------------------------------------
Router.js
window.cpd = window.cpd || {};
cpd.routers = cpd.routers || {};

cpd.routers.AppRouter = Backbone.Marionette.AppRouter.extend({
    appRoutes : {
        '' : 'CaseFoldersWindow',
        'index': 'CaseFoldersWindow',


        // Takes no input query, page is reset in PC every time its visited
    },

    //  Flexible customization of Backbone.Router.route in order to trigger a 'beforeroute' event before routing.
    //  This event could be particularly useful for managing the regions, append classes and loaders and for the mobile version (ex. integration with jQuery mobile)
    route : function(route, name, callback) {
        return Backbone.Router.prototype.route.call(this, route, name, function() {
            // this.trigger.apply(this, ['beforeroute:' + name].concat(_.toArray(arguments)));
            this.trigger.apply(this, ['beforeroute'].concat(_.toArray(arguments)));
            this.trigger.apply(this, ['onRoute'].concat(route, name, arguments));

            callback.apply(this, arguments);
        });
    }
});
--------------------------------------------view .js---------------


window.cpd = window.cpd || {};
cpd.views = cpd.views || {};

cpd.views.CaseFoldersWindow = Backbone.Marionette.ItemView.extend({

    template :'CaseFoldersWindow/CaseFoldersWindow',    
    events : {

    },
    initialize : function() {
    console.log("CaseFoldersWindow of view call");
    },
    ready:function(){


    },

});
--------------------------------
controller --------------------

;(function() {

    cpd.pages.CaseFoldersWindow = cpd.PageController.extend({
        regions : {
        mainRegion : '.outer',
        },
        template : {
        regionTemplate : 'CaseFoldersWindow/CaseFoldersWindow', 
        },
        events : {

        },
        init : function() {

            App.views.CaseFoldersWindow = new cpd.views.CaseFoldersWindow;
            this.region('mainRegion').show(App.views.CaseFoldersWindow);    

        },
    });
})();
-------------------------------------
temples -------------

<div class="outer">

</div>

<div >
Hello
</div>
4

1 回答 1

0

您在标题中输入的错误来自您尝试在 HTML 元素上使用 jQuery 方法,而不是 jQuery 元素。至于为什么您似乎总是在 jQuery 元素上使用它,我不确定。话虽这么说,你不应该做这样的事情:

_this.$el = $el;
_this.el = _this.$el.first();

而是使用View#setElement。问题可能来自代码中的某个地方,您在更改元素时出错。此外,_this.el = _this.$el.first():first似乎返回一个数组,而不是 HTML 元素。最后但同样重要的是,为什么要这样做_this.$el = $(_this.el);_this.$el应该已经包含这个值。

如果清理你的代码不能解决问题,我会问一个 jsfiddle,就像 David Sulc 提到的那样。

于 2013-06-12T13:37:20.380 回答