如何将Backbone.View到一个“单”DOM元素结合在DOM中类似的元素列表 [英] How to bind a Backbone.View to a 'single' DOM element in a list of similar elements in the DOM

查看:134
本文介绍了如何将Backbone.View到一个“单”DOM元素结合在DOM中类似的元素列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的页面结构:

<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>

下面是过于简单化查看:

Here is the overly simplistic View:

  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!");
        }
  });

问:我想知道被点击后的数据ID。与简单的jQuery我可以做到以下几点:

Question: I want to know the data Id of post that was clicked. With simple JQuery I can just do the following:

$('.wcCheckbox').live('click' function() {
    alert("Data id of post = "+$(this).parents('.WCPost').data('data-postId'));
}

现在我知道,做骨干事件委派所以它需要在EL财产DOM引用。如果我给它.listOfPosts那么事件似乎火完美,但得到其中的帖子进行了检查我将必须继续遍历DOM并挑选出被选中的元素!这将是在我看来,相当昂贵!我如何为每个岗位做到这一点的?骨干即如何绑定认为每一个人li.WCPost?

Now I know that Backbone does event delegation so it needs a DOM reference in the el property. If I give it the .listOfPosts then the event seems to fire perfectly but to get "which" posts were checked I'll have to keep traversing the DOM and pick out the elements that were selected!!! It would be quite expensive in my opinion! How do I do this in Backbone for each individual post?? i.e., How do I bind the view to each individual li.WCPost??

请注意:我不使用普通的香草jQuery的,因为code,我需要写与骨干网的模块化设计是最好的做法,但因为我不是一个亲与骨干网(但)只是有点迷茫...

NOTE: I'm not using plain vanilla jQuery since the code that I need to write is best done with Backbone's modular design, but since I'm not a pro with Backbone (yet ;) just a bit confused...

推荐答案

使用类似 $(event.target)。数据(帖子ID') postClicked()功能是做这样的东西,一个正常的方式,据我可以告诉。

Using something like $(event.target).data('postId') in your postClicked() function is a normal way to do this kind of stuff, as far as I can tell.

事件的广泛使用可能会在第一次看似寻常,但它是提高code组织的好方法,如果使用得当。你真的可以得到所有你想从该事件中的数据在大多数情况下,特别是如果你有jQuery的。 (请注意,传递给你的 postClicked 函数的事件是一个普通的jQuery事件对象和的,你可以找到关于它的可以应用于一切Backbone.js的的使用 jQuery的委托()函数绑定的事件。)

Extensive usage of events might seem unusual at first, but it's a good way to improve code organization, if used properly. You really can get all the data you want from the event in most cases, especially if you have jQuery. (Note that the event passed to your postClicked function is a regular jQuery event object, and everything you can find about it could be applied. Backbone.js uses jQuery's delegate() function to bind events.)

不过,你仍然可以通过自己在您的视图的初始化()方法绑定事件。

However, you still can bind events by yourself in the initialize() method of your view.

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");
},

这$(LT;选择&GT;)是一种功能,可自动作用域jQuery选择到视图,相当于 $(小于选择&gt;中this.el)

(this.$(<selector>) is a function that automatically scopes jQuery selectors to your view, equivalent to $(<selector>, this.el).)

另一种解决方案(也许是最自然的,最终,但是需要一点在第一部作品)是创建一个后览类,并用它为个人的职位和绑定复选框,单击事件。

Another solution (perhaps the most natural in the end, however requiring a bit of work at first) is to create a PostView class, and use it for individual posts and for binding checkbox click event.

要显示的帖子,在您的文章列表视图你通过帖子集合,为每个视图发表实例,并将其附加到 .listOfPosts 元素。

To display the posts, in your post list view you go through Posts collection, create a view for each Post instance, and append it to the .listOfPosts element.

您将不需要再解决后访问的ID的一个问题,因为你会在后览的复选框,单击事件绑定。因此,在处理函数将能够找到帖子的ID很容易,无论是通过相关模型( this.model.get('身份证')),或通过视图的元素( $(this.el)。数据(帖子ID'))。

You won't need to solve a problem of accessing post's ID anymore, since you would bind the checkbox click event on a PostView. So, in the handler function would be able to find post's ID easily—either through related model (this.model.get('id')) or through view's element ($(this.el).data('postId')).

现在,我'独立骨干的DOM怎么我产生我的帖子就像我在问题中提到改造为了每一个职位?

Now that I generated my posts' DOM independently of Backbone how do I 'retrofit' a view to each post like I mentioned in the question?

我不希望重构一吨的客户端code的只是为了满足骨干。但我怎么绑定,以便每个李??

I don't want to refactor a ton of client code just to accommodate Backbone. But how do I bind a view to each li??

如果你决定去与MVC和面向对象的JavaScript,你不应该管理的DOM元素将文章直接:创建后览情况下,他们在转,创建相应的元素,如在todos.js,并呈现模板填充。 (如果你不想自动创建元素,骨干网可以让你新创建的视图中手动绑定到的元素,通过指定属性继承。这样一来,当你可以绑定意见现有元素,例如,在初始页面加载)与特定职位的任何修改DOM应采取后览类里面的地方。

If you decided to go with MVC and object-oriented JavaScript, you shouldn't manage DOM elements for your posts directly: you create PostView instances, and they, in turn, create corresponding elements, like in todos.js, and fill them with rendered template. (And if you don't want to create elements automatically, Backbone allows you to bind newly created view to the element manually, by specifying el attribute when subclassing. This way, you can bind views to existing elements, for example, on the initial page load.) Any DOM modification related to particular posts should take place inside the PostView class.

OOP方式在基于DOM的一些优点:

Some advantages of OOP approach over DOM-based:


  • 视图更适合数据存储比DOM元素。

  • Views are more suitable for data storage than DOM elements.

请注意,以你目前的做法你使用数据属性广泛,例如,存储后的ID。但你并不需要做的,如果你操作的观点:每个后览已经知道其相关模型,这样你就可以轻松获得通过,如的帖子ID , view.model.get('帖子ID'),以及所需的任何其他职位的数据。

Note that with your current approach you're using data attributes extensively—for example, to store post's ID. But you don't need to do that if you're operating views: each PostView already knows about its related model, and so you can easily get the post id via, e.g., view.model.get('postId'), as well as any other post data that you want.

您还可以存储的视图特定的data 的不属于发布模式:例如,动画和/或显示状态(扩大,选择,...)

You can also store view-specific data that doesn't belong to Post model: for example, animation and / or display state (expanded, selected, …).

视图是更适合于确定元件的行为。

Views are more suitable for defining the behaviour of elements.

如果你想,例如,指定每个职位的复选框,单击事件处理程序,你把这个code到后览类。这样一来,的事件处理程序知道的所有数据后的,因为视图能够访问它。此外,的的code为更好地组织的 - 什么特别帖交易,属于后览,并在你的方式没有得到。

If you want to, for example, specify a checkbox click event handler for each post, you place this code into your PostView class. This way, event handler knows about all post data, because the view has access to it. Also, the code is better structured—what deals with particular posts, belongs to PostView, and doesn't get in your way.

另一个例子是公约定义的视图中的渲染()功能。模板函数或模板字符串存储在一个视图属性模板渲染()将呈现模板,填充鉴于与生成的HTML元素:

Another example is a convention to define a render() function on the view. The template function or template string is stored in a view attribute template, and render() renders that template and fills the view's element with resulting HTML:

render: function() {
    $(this.el).html(this.template({
        modelData: this.model.toJSON()
    }));
},


  • 处理DOM可能比操纵对象的要慢。

  • Manipulating DOM may be slower than manipulating objects.

    然而,DOM为基础的方法(这似乎是你使用到现在为止)都有自己的优点,特别是对于不太复杂的应用程序。另请参阅:面向对象的JavaScript与纯jQuery和存储。数据

    However, DOM-based approach (which seems like you were using until now) has its own pros, especially for less complicated applications. See also: Object Oriented Javascript vs. Pure jQuery and .data storage

    有没有意见结合到不是由骨干产生的当前和未来的DOM元素的方法吗?

    Is there a way to bind views to current and future DOM elements that are NOT generated by backbone?

    这是否意味着骨干需要从使用一开始,将很难'改造'这么说?

    Does that imply that backbone needs to be use from the very start and will be difficult to 'retrofit' so to speak?

    从上面下面,你并不需要绑定视图的将来的DOM元素(使用视图来操纵它们)。

    As follows from above, you don't need to bind views to future DOM elements (use views to manipulate them).

    对于绑定到已经在页面上时,它的初始化,我不知道正确的方式做到这一点的DOM元素。我目前的做法是清除现有的元素,并从头开始创建的意见,这将自动创建相应的DOM元素。

    Regarding binding to the DOM elements that are already on the page when it's initialized, I don't know the ‘right’ way to do that. My current approach is to clear existing elements and create views from scratch, which would automatically create corresponding DOM elements.

    这意味着浏览器会产生一些额外的工作,在页面初始化的事情。对我来说,OOP的优势证明它。但从用户的角度来看,它也很好,我想:初始初始化之后,一切都将工作得更快,因为网页将不再需要用户之前,确实像注销重新加载

    This means browser will have some extra work to do at page initialization. For me, advantages of OOP justify it. From the user's point of view, it's also fine, I guess: after that initial initialization, everything will work faster, since page won't need to be reloaded until user does something like logout.

    (顺便说一句,我想我应该澄清使用MVC的办法,至少,对我的一点:创建一个客户端应用程序,从本质上讲,本身并不最多的工作,利用后端提供的API服务器。服务器中的JSON为模型提供数据,以及您的客户端应用程序没有休息,广泛使用AJAX。如果你做正常的页面加载时用户与您的网站交互,那么这样的MVC和重型客户端可能是开销为你。另一件事是,你将不得不重构一些code,这可能不是根据您的要求和资源的一个选项。)

    (BTW, I think I should clarify the point of using MVC approach, at least, for me: creating a client-side application that, essentially, does the most work by itself, using the API provided by the back-end server. Server provides data in JSON for models, and your client-side app does the rest, extensively using AJAX. If you do normal page loads when user interacts with your site, then such MVC and heavy client-side might be overhead for you. Another thing is that you will have to refactor some code, which may not be an option depending on your requirements and resources.)

    这篇关于如何将Backbone.View到一个“单”DOM元素结合在DOM中类似的元素列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆