Javascript 我可以在不手动跟踪模糊事件的情况下将表单输入绑定到 Backbone.js 中的模型吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4074636/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 07:22:14  来源:igfitidea点击:

Can I bind form inputs to models in Backbone.js without manually tracking blur events?

javascriptjqueryhtmlbackbone.js

提问by Julien

I have a backbone.js app (www.github.com/juggy/job-board) where I want to bind my form inputs directly to my model (a la Sproutcore).

我有一个backbone.js 应用程序(www.github.com/juggy/job-board),我想将表单输入直接绑定到我的模型(la Sproutcore)。

Is it possible with Backbone.js (or other tools) without actually tracking each blur events on the inputs and updating the model manually? This seems like a lot of glue code.

是否可以使用 Backbone.js(或其他工具)而不实际跟踪输入上的每个模糊事件并手动更新模型?这看起来像很多胶水代码。

Thanks,
Julien

谢谢,
朱利安

采纳答案by clyfe

I'm not sure how SC does it but probably they listen for events too.

我不确定 SC 是如何做到的,但可能他们也会监听事件。

window.SomeView = Backbone.View.extend({
  events: {
    "change input.content":  "contentChanged"
  },
  initialize: function() {
    _.bindAll(this, 'contentChanged');
    this.inputContent = this.$('input.content');
  },
  contentChanged: function(e) {
    var input = this.inputContent;

    // if you use local storage save 
    this.model.save({content: input.val()});

    // if you send request to server is prob. good idea to set the var and save at the end, in a blur event or in some sync. maintenance timer.
    // this.model.set({content: input.val()});
  }
});

回答by Malcolm Sharman

There is an even nicer way to handle this if your model includes lots of properties in it.

如果您的模型包含许多属性,则有一种更好的方法来处理此问题。

SampleView = Backbone.View.extend({
    el: "#formEl",

    events: {
        "change input": "changed",
        "change select": "changed"
    },

    initialize: function () {
        _.bindAll(this, "changed");
    },

    changed:function (evt) {
       var changed = evt.currentTarget;
       var value = $(evt.currentTarget).val();
       var obj = {};
       obj[changed.id] = value;
       this.model.set(obj);
    }
 });

There is a reliance on your input elements having an id the same as the what the name of the property in your model is.

依赖于具有与模型中属性名称相同的 id 的输入元素。

回答by LoG

I think this is a cleaner (and maybe faster) way to create an object from an input element

我认为这是一种从输入元素创建对象的更简洁(也许更快)的方法

changed: function(evt) {
  var target = $(evt.currentTarget),
      data = {};
  data[target.attr('name')] = target.val();
  this.model.set(data);
},

without jquery:

没有jQuery:

changed: function(evt) {
  var target = evt.currentTarget,
      data = {};
  data[target.name] = target.value;
  this.model.set(data);
},

回答by Bruno Reis

Have you tried Backbone.ModelBinder? It′s a nice tool to do what you need: https://github.com/theironcook/Backbone.ModelBinder

你试过 Backbone.ModelBinder 吗?这是一个很好的工具来做你需要的:https: //github.com/theironcook/Backbone.ModelBinder

回答by Jens Alm

I'm working on corset, a form library for backbone.js inspired by the django forms module, but a little less ambitious in scope. Still working out the kinks, but it'll end up on github when at least semi-stable and functional.

我正在研究 corset,这是一个由 django 表单模块启发的用于backbone.js 的表单库,但在范围上没有那么雄心勃勃。仍在解决问题,但它最终会在 github 上至少处于半稳定和功能状态。

The aim of corset is to have easily subclassed field classes so that you can build complex inputs for more complex use cases (cascading selects, etc). This approach renders each field as a separate view, and the form view is bound to a model and uses change events, blur events or submit events to update the model (configurable, blur is default). Each view has an overrideable getData function that per default maps to the jquery .val() function.

corset 的目标是拥有易于子类化的字段类,以便您可以为更复杂的用例(级联选择等)构建复杂的输入。这种方法将每个字段呈现为一个单独的视图,表单视图绑定到一个模型,并使用更改事件、模糊事件或提交事件来更新模型(可配置,默认为模糊)。每个视图都有一个可覆盖的 getData 函数,该函数默认映射到 jquery .val() 函数。

Using sensible defaults and a modelFormFactory function, we use corset (or the subset of it that is actually done yet) for rapid development, define a model using sensible attribute names, use modelFormFactory and you have instant edit UI.

使用合理的默认值和 modelFormFactory 函数,我们使用 corset(或实际完成的它的子集)进行快速开发,使用合理的属性名称定义模型,使用 modelFormFactory 并且您拥有即时编辑 UI。

回答by bradgonesurfing

I created the following technique on my site

我在我的网站上创建了以下技术

class FooView extends MyView

  tag: "div"

  modelBindings:

    "change form input.address" : "address"
    "change form input.name"    : "name"
    "change form input.email"   : "email"

  render: ->

    $(@el).html """
      <form>
        <input class="address"/>
        <input class="name"/>
        <input class="email"/>
      </form>
    """

    super

    @


# Instantiate the view 
view = new FooView
  model: new Backbone.Model

$("body").html(view.el) 

I've detailed the extensions to backbone you need to make on my blog

我在我的博客上详细介绍了您需要对主干进行的扩展

http://xtargets.com/2011/06/11/binding-model-attributes-to-form-elements-with-backbone-js/

http://xtargets.com/2011/06/11/binding-model-attributes-to-form-elements-with-backbone-js/

it uses the same declarative style as the events property for binding form elements to model attributes

它使用与 events 属性相同的声明样式来将表单元素绑定到模型属性

and here is the actual code implementing the class for you in coffeescript

这是在 coffeescript 中为您实现类的实际代码

class MyView extends Backbone.View

  render: ->

    if @model != null
      # Iterate through all bindings
      for selector, field of @modelBindings
        do (selector, field) =>
          console.log "binding #{selector} to #{field}"
          # When the model changes update the form
          # elements
          @model.bind "change:#{field}", (model, val)=>
            console.log "model[#{field}] => #{selector}"
            @$(selector).val(val)

          # When the form changes update the model
          [event, selector...] = selector.split(" ")
          selector = selector.join(" ")
          @$(selector).bind event, (ev)=>
            console.log "form[#{selector}] => #{field}"
            data = {}
            data[field] = @$(ev.target).val()
            @model.set data

          # Set the initial value of the form
          # elements
          @$(selector).val(@model.get(field))

    super

    @

Appologies if you don't like coffeescript. I do. Everybody is different :)

如果您不喜欢咖啡脚本,请道歉。我愿意。每个人都不一样:)