我是骨干的新手。我创建了一个使用MVC显示“Hello”的新项目。但我收到了错误 这个文件backbone.marionette.js 此错误
未捕获的TypeError:对象
没有方法'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>
答案 0 :(得分: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
应该已包含此值。
如果清理代码无法解决问题,我会问David Sulc提到的jsfiddle。