简体   繁体   English

使用 Backbone.ModelBinder 向元素添加属性值的类

[英]Add class to elements for values of attribute with Backbone.ModelBinder

I'm using Backbone.ModelBinder in a Backbone.js Marionette project.我在 Backbone.js Marionette 项目中使用 Backbone.ModelBinder。 I've a scenario which I can't work out how to use ModelBinder to automatically update my model/UI.我有一个场景,我无法弄清楚如何使用 ModelBinder 自动更新我的模型/UI。

My model has a 'status' string attribute, with multiple states.我的模型有一个 'status' 字符串属性,有多个状态。 In this example I'll show the code for two: 'soon', 'someday'在这个例子中,我将展示两个代码:'soon', 'someday'

In my UI I have a list on which I use click events to set the model status, and update classes to highlight the relevant link in the UI.在我的 UI 中,我有一个列表,我在该列表上使用单击事件来设置模型状态,并更新类以突出显示 UI 中的相关链接。

<dd id="status-soon"><a>Soon</a></dd>
<dd id="status-someday" class="active"><a>Someday</a></dd>

events: {
    'click #status-soon': 'setStatusSoon',
    'click #status-someday': 'setStatusSomeday'
},
setStatusSoon: function () {
    this.model.set('status', 'soon');
    this.$el.find('.status dd').removeClass('active');
    this.$el.find('#status-soon').addClass('active');
},
... etc

It feels like I doing this a long-winded and clunky way!感觉我这样做是一种冗长而笨拙的方式! The code bloat increases with the number of states I need to support.代码膨胀随着我需要支持的状态数量而增加。 What's the best way of achieving the same outcome with ModelBinder?使用 ModelBinder 实现相同结果的最佳方法是什么?

You could probably simplify things with a data attribute, something like this:您可能可以使用数据属性简化事情,如下所示:

<dd data-status="soon" class="set-status"><a>Soon</a></dd>
<dd data-status="someday" class="set-status active"><a>Someday</a></dd>

and then:进而:

events: {
    'click .set-status': 'setStatus'
},
setStatus: function(ev) {
    var $target = $(ev.target);
    var status  = $target.data('status');
    this.model.set('status', status);
    this.$el.find('.status dd.set-status').removeClass('active');
    $target.addClass('active');
}

You might not need the set-status class, just keying things on the <dd> s might be sufficient;您可能不需要set-status类,只需在<dd>上键入内容就足够了; I prefer separating my event handling from the nitty gritty element details though.不过,我更喜欢将我的事件处理与细节元素细节分开。

Unfortunately, it is going to be pretty difficult to do exactly what you want with ModelBinder .不幸的是,使用ModelBinder完全做到你想要的将是非常困难的。 The main reason being that ModelBinder wants to provide the same value for all elements that are part of a single selector.主要原因是ModelBinder希望为属于单个选择器的所有元素提供相同的值。 So doing this with ModelBinder , while possible, is going to be pretty verbose as well.因此,使用ModelBinder执行此ModelBinder虽然可能,但也会非常冗长。

The cleanup offered by mu is likely to be better than trying to use ModelBinder . mu 提供的清理可能比尝试使用ModelBinder更好。 1) because you need a click handler to do the this.model.set no matter what and 2) you would need individual bindings for ModelBinder because the converter function is called once for a single selector and then the value is set on all matching elements (rather than looping through each one). 1) 因为this.model.set您都需要一个点击处理程序来执行this.model.set和 2) 您需要为ModelBinder单独绑定,因为转换器函数为单个选择器调用一次,然后在所有匹配元素上设置该值(而不是遍历每个)。

But if you do want to try and do something with ModelBinder it would look something like this:但是如果你真的想尝试用ModelBinder做一些事情,它看起来像这样:

  onRender : function () {
    var converter = function (direction, value) { 
      return (value == "soon" ? "active" : "");
    };
    var bindings = {
      status : {selector : "#status-soon", elAttribute : "class", converter : converter}
    };
    this.modelBinder.bind(this.model, this.el, bindings);
  }

This would do what you want.这会做你想做的。 Of course the down side as I said above is that you will need multiple selector bindings.当然,正如我上面所说的,不利的一面是您将需要多个选择器绑定。 You could generalize the converter using this.boundEls[0] but you will still need the separate bindings for it to work.您可以使用this.boundEls[0]来概括转换器,但您仍然需要单独的绑定才能使其工作。

In case you want to access to the bound element, it is possible to declare 'html' as elAttrbute, modify the element and return its html with converter function:如果您想访问绑定元素,可以将 'html' 声明为 elAttrbute,修改元素并使用转换器函数返回其 html:

onRender : function () {
  var converter = function (direction, value, attribute, model, els) {
    return $(els[0]).toggleClass('active', value === 'soon').html();
  };
  var bindings = {
    status : {
      selector : "#status-soon", 
      elAttribute : "html", 
      converter : converter
    }
  };
  this.modelBinder.bind(this.model, this.el, bindings);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM