第一次使用Marionette,当我尝试渲染CompositeView时,我遇到了'itemViewContainer'属性的问题。
我已经让CompositeView在同一个应用程序中工作,但在这种情况下,我试图在用户点击按钮时呈现'PopupView'。在这个弹出窗口中,有一个由没有出现的CompositeView呈现的表。
这是用户可以打开弹出窗口的视图。这是CompositeView中的一个项目。
define([
'marionette',
'templates',
'views/SectionPopupView'
], function(
Marionette,
templates,
SectionPopupView
) {
/** ClassListingRowView represents a row in the ClassListingView.
* Each Row is tied to a specific Course object that's passed in
* when the Row is instantiated in ClassListingView.
* this.model: Course model
* this.options.user: User model */
return Marionette.ItemView.extend({
template: templates.classListingRow,
className: 'class-listing',
popupView: null,
ui: {
'editBtn': 'a.edit-btn',
'removeBtn': 'a.remove-btn',
'popupContainer': 'div.popup-container'
},
events: {
'click @ui.editBtn': 'editCourse',
'click @ui.removeBtn': 'removeCourse'
},
/** Set the ID of this element to [UID]-listing. Also fetches data
* from the model. */
// TODO: This calls render() twice... how do I make it better?
initialize: function() {
this.user = this.options.user;
$(this.$el).attr('id', this.model.get('UID') + '-listing');
var self = this;
this.model.fetch({
success: function() {
self.render();
}
});
},
/** Spawns a popup with all sections that allows a user to choose
* which sections he/she does/doesn't want. */
editCourse: function(e) {
e.preventDefault();
e.stopPropagation();
var self = this;
// Instantiate a view if it hasn't already been instantiated
$(window.app.curtain).show();
if (this.popupView == null) {
this.popupView = new SectionPopupView({
el: self.ui.popupContainer,
model: self.model
});
this.popupView.render();
} else {
this.popupView.show();
}
},
/** Removes this.course from the User's selectedCourse list.
* This will trigger an event which the ClassListingView should be
* listening for, and then this View will be discarded. */
removeCourse: function(e) {
e.preventDefault();
e.stopPropagation();
this.user.removeCourseFromSelected(this.model);
}
});
});
这是弹出窗口的视图:
define([
'marionette',
'templates',
'views/PopupView',
'views/SectionTableView',
'jquery'
], function(
Marionette,
templates,
PopupView,
SectionTableView,
$
) {
/** A SectionPopupView is a View that represents a popup that shows all of
* the sections for a particular Course and allows a user to select
* which sections he wants to include and also to see more information
* about the course.
* model: Course */
var SectionPopupView = PopupView.extend({
template: templates.sectionPopup,
sectionTable: null,
ui: {
'closeBtn': 'a.close',
'tableContainer': 'div#table-container',
'okBtn': 'a#submit'
},
events: {
'click @ui.closeBtn': 'close',
'click @ui.okBtn': 'continue'
},
/** Upon initialization, the View will have been instantiated with
* model: Course. A SectionListTableView must be instantiated upon
* init and populated with data from the model's sections attr. */
initialize: function() {
var self = this;
this.on('render', function() {
self.sectionTable.render();
});
this.sectionTable = new SectionTableView({
el: self.ui.tableContainer,
model: self.model
});
// this.sectionTable.render();
},
/** Hides the popup (and curtain). */
show: function() {
$(window.app.curtain).show();
$(this.el).show();
},
/** Shows the popup (and curtain). */
close: function(e) {
e.preventDefault();
e.stopPropagation();
$(window.app.curtain).hide();
$(this.el).hide();
}
});
return SectionPopupView;
});
这里是表格的视图(sectionTable)
define([
'marionette',
'templates',
'views/SectionTableRowView',
'views/NoSectionsView',
'jquery'
], function(
Marionette,
templates,
SectionTableRowView,
NoSectionsView,
$
) {
/**
* this.model = Course */
return Marionette.CompositeView.extend({
template: templates.sectionTable,
itemView: SectionTableRowView,
itemViewContainer: 'tbody',
emptyView: NoSectionsView,
initialize: function() {
this.itemViewOptions = {
user: this.model
};
}
});
});
我在这里读到很多人都有这个问题,因为他们试图在DOM之前渲染视图,所以我将表格的渲染功能绑定到弹出窗口的渲染事件,但这也没有用。有帮助吗?
除此之外,我是否对MVC指南/最佳实践等做了错误的处理?我对我的代码没有100%的信心,所以反馈也会受到赞赏!感谢。
答案 0 :(得分:0)
有几件事:
1)您的this.on("render"...
代码需要通过正确的上下文(我相信这有效):
this.on("render", function() {
this.sectionTable.render();
}, this);
这一点可以移动到此视图的onRender
函数,这有助于清晰:
onRender: function() {
this.sectionTable.render();
}
2)了解木偶在DOM周围使用的信号非常重要:
当该视图的onRender
已在虚拟DOM中完全构建但在将其插入用户的(/ jQuery可访问的)DOM之前, $el
方法被调用
onShow
调用 $el
方法,以便该视图在DOM中成功访问,并且可以访问jQuery。
有一些onShow
边缘情况可以出现,通常只有在深度嵌套布局时才会发生。如果你很好奇我写了here。