PhD*_*PhD 5 javascript jquery backbone.js
我有以下页面结构:
<ul class="listOfPosts">
<li class="post WCPost" data-postId="1">
<div class="checkbox"><input type="checkbox" class="wcCheckbox"/></div>
<div class="PostContainer>
<!-- some other layout/content here -->
<ul class="listOfLabels">
<li class="label"> Label 1</li>
<li class="label"> Label 2</li>
</ul>
</div>
</li>
<li class="post WCPost" data-postId="2">...</li>
<li class="post WCPost" data-postId="3">...</li>
<li class="post WCPost" data-postId="4">...</li>
...
</ul>
Run Code Online (Sandbox Code Playgroud)
这是过于简单化的视图:
var MyView = Backbone.View.extend({
el:$('.listOfPosts'),
initialize: function() {
_.bindAll(this,"postClicked");
},
events: {
"click .wcCheckbox":"postClicked"
},
postClicked: function() {
alert("Got a a click in the backbone!");
}
});
Run Code Online (Sandbox Code Playgroud)
问题:我想知道被点击的帖子的数据ID.使用简单的JQuery,我可以执行以下操作:
$('.wcCheckbox').live('click' function() {
alert("Data id of post = "+$(this).parents('.WCPost').data('data-postId'));
}
Run Code Online (Sandbox Code Playgroud)
现在我知道Backbone执行事件委托,因此它需要el属性中的DOM引用.如果我给它.listOfPosts然后事件似乎完全开火但是要检查"哪个"帖子我将不得不继续遍历DOM并挑选出被选中的元素!在我看来,这将是相当昂贵的!我如何在Backbone中为每个帖子做这个?即,如何将视图绑定到每个单独的li.WCPost ??
注意:我没有使用普通的vanilla jQuery,因为我需要编写的代码最好用Backbone的模块化设计完成,但是因为我不是Backbone的专业人员(还有),有点困惑......
据我所知,$(event.target).data('postId')在你的postClicked()函数中使用类似的东西是做这种事情的常用方法.
事件的广泛使用起初可能看起来很不寻常,但如果使用得当,这是改善代码组织的好方法.在大多数情况下,你真的可以从事件中获得所需的所有数据,特别是如果你有jQuery.(请注意,传递给您的postClicked函数的事件是一个常规的jQuery事件对象,您可以找到有关它的所有内容 .Backbone.js 使用 jQuery的delegate()函数来绑定事件.)
但是,您仍然可以在initialize()视图的方法中自己绑定事件.
initialize: function() {
// Custom binding code:
this.$('.wcCheckbox').live('click' function() {
alert("Data id of post = "+$(this).parents('.WCPost').data('data-postId'));
}
// No need for this anymore:
// _.bindAll(this,"postClicked");
},
Run Code Online (Sandbox Code Playgroud)
(this.$(<selector>)是一个自动将jQuery选择器作用于视图的函数,相当于$(<selector>, this.el).)
另一种解决方案(最终可能是最自然的,但最初需要一些工作)是创建一个PostView类,并将其用于单个帖子和绑定复选框点击事件.
要显示帖子,请在帖子列表视图中浏览Posts集合,为每个Post实例创建视图,然后将其附加到.listOfPosts元素.
您将不再需要解决访问帖子ID的问题,因为您将绑定复选框点击事件PostView.因此,在处理程序中,函数可以轻松地通过相关的模型(this.model.get('id'))或通过视图的元素($(this.el).data('postId'))来查找帖子的ID .
既然我独立于Backbone创建了帖子的DOM,我如何像我在问题中提到的那样"改进"每个帖子的视图?
我不想重构大量的客户端代码只是为了容纳Backbone.但是如何将视图绑定到每个li?
如果您决定使用MVC和面向对象的JavaScript,则不应直接管理帖子的DOM元素:您创建PostView实例,然后它们创建相应的元素,如todos.js,并用渲染填充它们模板.(如果您不想自动创建元素,Backbone允许您通过el在子类化时指定属性来手动将新创建的视图绑定到元素.这样,您可以将视图绑定到现有元素,例如,在初始页面上load.)任何与特定帖子相关的DOM修改都应该在PostView类中进行.
OOP方法优于基于DOM的一些优点:
视图比DOM元素更适合数据存储.
请注意,使用您当前的方法,您可以data广泛使用属性 - 例如,存储帖子的ID.但是如果您正在操作视图,则不需要这样做:每个人都PostView已经了解其相关模型,因此您可以轻松地通过例如view.model.get('postId')您想要的任何其他帖子数据获取帖子ID .
您还可以存储不属于Post模型的视图特定数据:例如,动画和/或显示状态(展开,选定,...).
视图更适合定义元素的行为.
例如,如果您要为每个帖子指定一个复选框单击事件处理程序,则将此代码放入您的PostView类中.这样,事件处理程序就可以了解所有发布数据,因为视图可以访问它.此外,代码更好的结构 - 什么处理特定的帖子,属于PostView,并没有妨碍你.
另一个例子是render()在视图上定义函数的约定.模板函数或模板字符串存储在视图属性中template,并render()呈现该模板并使用生成的HTML填充视图的元素:
render: function() {
$(this.el).html(this.template({
modelData: this.model.toJSON()
}));
},
Run Code Online (Sandbox Code Playgroud)操纵DOM可能比操纵对象慢.
但是,基于DOM的方法(看起来就像你现在使用的那样)有其自己的优点,特别是对于不那么复杂的应用程序.另请参阅:面向对象的Javascript与纯jQuery和.data存储
有没有办法将视图绑定到非骨干生成的当前和未来DOM元素?
这是否意味着骨干需要从一开始就使用,并且很难"改造"这么说?
如上所述,您不需要将视图绑定到将来的 DOM元素(使用视图来操作它们).
关于绑定到初始化时已经在页面上的DOM元素,我不知道这样做的"正确"方法.我目前的方法是清除现有元素并从头创建视图,这将自动创建相应的DOM元素.
这意味着浏览器在页面初始化时还需要做一些额外的工作.对我来说,OOP的优势证明了这一点.从用户的角度来看,它也很好,我想:在初始初始化之后,一切都会更快,因为在用户执行注销之前不需要重新加载页面.
(顺便说一下,我认为我应该澄清使用MVC方法的重点,至少对我来说:创建一个客户端应用程序,基本上,使用后端服务器提供的API,本身最能完成工作.为模型提供JSON数据,你的客户端应用程序完成剩下的工作,广泛使用AJAX.如果你在用户与你的站点交互时进行正常的页面加载,那么这样的MVC和沉重的客户端可能是你的开销.是你必须重构一些代码,根据你的要求和资源,这可能不是一个选项.)
| 归档时间: |
|
| 查看次数: |
6681 次 |
| 最近记录: |