Pytanie Czy mogę powiązać dane wejściowe formularzy z modelami w Backbone.js bez ręcznego śledzenia zdarzeń z rozmyciem?


Mam aplikację backbone.js (www.github.com/juggy/job-board) gdzie chcę powiązać moje dane wejściowe bezpośrednio z moim modelem (a la Sproutcore).

Czy jest to możliwe z Backbone.js (lub innymi narzędziami) bez faktycznego śledzenia każdego zdarzenia rozmycia na wejściach i ręcznego aktualizowania modelu? Wydaje się, że jest to dużo kodu kleju.

Dzięki,
Julien


62
2017-11-02 03:00


pochodzenie




Odpowiedzi:


Nie wiem, jak SC to robi, ale pewnie też słuchają wydarzeń.

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()});
  }
});

34
2017-11-09 10:18



W końcu to zrobiłem. Do tej pory pracuję świetnie. Jak powiedziałeś, zapisuje się przy każdej zmianie wejścia. Błędy są wyświetlane natychmiast, co jest dobre i złe (niezmodyfikowane pola wyświetlałyby błędy, które nie mogą być puste podczas tworzenia rekordu). - Julien
1. można również spróbować zdarzenie blur. 2. Zastanawiam się nad tym zagadnieniem, warto byłoby mieć tablicę "powiązań" podobną do tablicy "zdarzeń", która określa aktualizacje między częściami widoku a atrybutami modelu z parametrami typu synchronizacji (at_change, at_blur itp.) . podobni do bindings: [["div#title", "model.title", "change", "<-"], ["input#description", "model.description", "change", "<->"]]lub coś w tym stylu, powinno być całkiem łatwe do wdrożenia. - clyfe
Myślę, że możesz użyć Handlebar.js jako silnika szablonowego. Ma tego rodzaju wiązania. - Julien
@clyfe - hi, nie powinny czytać zdarzenia "change input.content": "contentChanged"? Chyba że czegoś mi brakuje. - UpTheCreek
Naprawiono @UpTheCreek - clyfe


Jest jeszcze lepszy sposób na obsłużenie tego, jeśli twój model zawiera wiele właściwości.

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

Istnieje zależność od elementów wejściowych posiadających identyfikator taki sam jak nazwa właściwości w modelu.


53
2018-03-01 21:15



Czy var obj = {} [changed.id] = wartość; działa lepiej niż: var obj = "{\" "+ zmienił.id +" \ ": \" "+ wartość +" \ "}"; var objInst = JSON.parse (obj); - btiernay
Nigdy nie należy polegać na czymś takim jak: "{\""+changed.id +"\":\""+value+"\"}" przynajmniej serializować / uciec ciąg wartości, jeśli musisz. - LoG
Ta sama idea została rozszerzona i zaimplementowana jako wtyczka: lostechies.com/derickbailey/2011/07/24/... - JamieJag
@porcoesphino przepraszam? Nie sądzę, że brałem udział w tym poście. - John Cromartie
@JohnCromartie, tak, post już tam nie ma. To było coś w stylu "to jest okropny sposób na jego wdrożenie" bez żadnego wyjaśnienia. Skasuję mój komentarz, ale najpierw: czy nadal uważasz, że to okropne? Jeśli tak, dlaczego? - porcoesphino


Myślę, że jest to czystszy (i być może szybszy) sposób tworzenia obiektu z elementu wejściowego

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

bez jquery:

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

18
2018-03-24 21:52



Nie musisz przekazywać obiektu do modelu.set (). Innymi słowy, możesz użyć następującego: this.model.set (target.name, target.value); - Joe Johnson


Próbowałeś Backbone.ModelBinder? To dobre narzędzie do robienia tego, czego potrzebujesz: https://github.com/theironcook/Backbone.ModelBinder


12
2018-06-29 02:58





Pracuję nad gorsetem, biblioteką formularzy dla backbone.js zainspirowaną modułem formularzy django, ale nieco mniej ambitnym pod względem zakresu. Nadal pracuję nad supłami, ale skończy się na githubie, gdy jest przynajmniej częściowo stabilny i funkcjonalny.

Celem gorsetu jest łatwe subklasowe klasy pól, dzięki czemu można budować złożone dane wejściowe dla bardziej złożonych przypadków użycia (kaskadowe zaznaczenia itp.). Podejście to renderuje każde pole jako osobny widok, a widok formularza jest powiązany z modelem i używa zdarzeń zmian, rozmycia lub przesłania zdarzeń w celu zaktualizowania modelu (konfigurowalne, domyślne ustawienie "zamazywanie"). Każdy widok ma nadpisywalną funkcję getData, która domyślnie odwzorowuje funkcję .val () jquery.

Używając rozsądnych wartości domyślnych i funkcji modelFormFactory, używamy gorsetu (lub jego podzestawu, który jest faktycznie gotowy) do szybkiego opracowania, zdefiniowania modelu przy użyciu sensownych nazw atrybutów, użycia modeluFormFactory i natychmiastowego interfejsu użytkownika.


0
2018-05-07 12:50



Chciałbym zobaczyć tę bibliotekę! Czy jest jeszcze dostępny? - bradgonesurfing
Niestety, nie jest jeszcze gotowa do ogólnej konsumpcji, ale mamy nadzieję, że uda się ją zdobyć w sierpniu (należy najpierw wysłać produkt, zanim będę mógł poświęcić czas na jego wyczyszczenie i uogólnienie) - Jens Alm


Na mojej stronie utworzyłem następującą technikę

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) 

Mam szczegółowe rozszerzenia do kręgosłupa, które musisz wprowadzić na moim blogu

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

używa on tego samego stylu deklaratywnego co właściwość events do wiązania elementów formularza modelować atrybuty

i tutaj jest rzeczywisty kod implementujący klasę dla ciebie w 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, jeśli nie lubisz coffeescript. Ja robię. Każdy jest inny :)


0
2018-06-11 21:11



Publikowanie wygenerowanych danych wyjściowych nie jest szczególnie przydatne w przypadku przykładów formatu CoffeeScript o dowolnym rozmiarze - jest brzydki i trudny do odczytania, ponieważ dane wyjściowe są przeznaczone dla tłumacza, a nie do odczytu. Nigdy nie pisałbyś w ten sposób JavaScript ręcznie. Z tego powodu zaskakuje mnie, że tak wiele przykładów Coffeescript robi to na końcu ze zwyczajową "JavaScript - eww!" - Jonny Buchanan
W dzisiejszych czasach nie możesz sprawić nikomu radości. Po prostu napisz coffeescript raymond narzeka. Dokonaj edycji, dołączając tłumaczenie i insynuacje. Biorąc pod uwagę, że pytanie dotyczyło wiązania formy w kręgosłupie, moja odpowiedź była na temat i prawdopodobnie najbardziej idiomatyczne rozwiązanie szkieletowe. Pytanie dotyczyło głównie jquery i szkieletu, a nie javascript. - bradgonesurfing
W dzisiejszych czasach kręgosłup jest starym kapeluszem. Powinieneś używać angularjs, jeśli chcesz mieć superaktywne wiązania. - bradgonesurfing