запазване на опорния модел, валидирането е неуспешно

никакво търсене в Гугъл не успява да разреши объркването ми, така че реших да задам въпроса тук.

Опитвам се да запазя модел и да използвам обратните извиквания успех/грешка. В основната документация се посочва, че запазвате своя модел така: model.save([attributes], [options]).

Не мога да намеря никъде в документацията, която да ви казва как да запазите целия модел (т.е. без да посочвате атрибутите), но попаднах на този въпрос, където вторият отговор казва, че можете да запазите целия модел, можете да направите model.save({}, [options]).

Въпреки това опитвам това без резултат. Моят код е по-долу:

Модел на гръбнака:

class Student extends Backbone.Model
  url: ->
    '/students' + (if @isNew() then '' else '/' + @id)

  validation:
    first_name:
      required: true
    last_name:
      required: true
    email:
      required: true
      pattern: 'email'

  schema: ->
    first_name:
      type: "Text"
      title: "First Name"
    last_name:
      type: "Text"
      title: "Last Name"
    email:
      type: "Text"
      title: "Email"

Според мен имам следната функция:

class Students extends CPP.Views.Base
  ...
  saveModel = ->
    console.log "model before", @model.validate()
    console.log "model attrs", @model.attributes
    @model.save {},
      wait: true
      success: (model, response) ->
        notify "success", "Updated Profile"
      error: (model, response) =>
        console.log "model after", @model.validate()
        console.log "model after is valid", @model.isValid()
        console.log "response", response
        notify "error", "Couldn't Update"

В първия console.log преди запазването ми се казва, че моделът е валиден, чрез средствата на отговор undefined. Ако наистина погледна модела, виждам, че и трите полета са попълнени.

По същия начин в следващите два журнала на конзолата в грешката @model.validate() и @model.isValid() връщат съответно undefined и true. Въпреки това отговорът, който получавам при опит да запазя модела, е Object {first_name: "First name is required", last_name: "Last name is required", email: "Email is required"}

Накрая в console.log на атрибутите на моделите получавам:

Object
  created_at: "2012-12-29 23:14:54"
  email: "[email protected]"
  first_name: "John"
  id: 2
  last_name: "Doe"
  type: "Student"
  updated_at: "2012-12-30 09:25:01"
  __proto__: Object

Това ме кара да вярвам, че когато предадох {} на моя модел, той всъщност се опитваше да запази атрибутите като нула, иначе защо би допуснал грешка?

Може ли някой любезно да ми посочи какво правя погрешно? Предпочитам да не се налага да подавам всеки атрибут поотделно към запазването!

Благодаря предварително


person Sarah Tattersall    schedule 30.12.2012    source източник


Отговори (2)


От предложения отговор от Hui Zheng модифицирах моя контролер в моя сървър, за да върна ученика във формат JSON.

Въпреки това, за да намеря истинския източник на проблема, прочетох основната документация при запазване и откри, че когато wait: true е дадено като опция, той изпълнява следното:

if (!done && options.wait) {
        this.clear(silentOptions);
        this.set(current, silentOptions);
}

При по-нататъшно разследване на ясно установих

clear: function(options) {
  var attrs = {};
  for (var key in this.attributes) attrs[key] = void 0;
  return this.set(attrs, _.extend({}, options, {unset: true}));
},

От това изглежда, че всеки атрибут се изчиства, за да бъде нулиран. Въпреки това при изчистване на моя модел валидациите, които написах, ще се провалят (тъй като са необходими first_name, last_name, email).

В документацията за backbone.validation ни се казва, че можем да използваме параметъра forceUpdate: true, така че избрах да използвам това, когато запазвам моя модел. Засега ще приема (въпреки че това може да не е добра практика), че данните от сървъра са правилни, тъй като това също е потвърдено.

Следователно моят окончателен код е:

saveModel = ->
  @model.save {},
    wait: true
    forceUpdate: true
    success: (model, response) ->
      notify "success", "Updated Profile"
    error: (model, response) ->
      notify "error", "Couldn't Update"
person Sarah Tattersall    schedule 30.12.2012
comment
Малко съм объркан. Мислех, че използвате Backbone 0.9.1 или 0.9.2, тъй като методът isValid е премахнат във версия 0.9.9. Но сега препращате към кодовия фрагмент в Backbone 0.9.9. Доколкото мога да разбера, методът clear не се извиква в метода save преди 0.9.9. Всъщност методът clear дори е премахнат в последната версия 0.9.9(raw.github.com /documentcloud/backbone/master/backbone.js). Което е по-лошо, метод isValid се съживява в тази последна версия. И така, коя версия всъщност използвате? - person Hui Zheng; 31.12.2012
comment
0.9.9, но сега съм объркан. В документацията се говори за ясно и наистина регистърът на промените (на backbonejs.org/)des наистина казва, че isValid е бил премахнат, но както посочихте, последната версия все още съдържа isValid. - person Sarah Tattersall; 02.01.2013
comment
Като бърза актуализация разбрах, че моят isValid идва от валидиране на гръбнака (github.com/thedersen/backbone .validation), а не самия гръбнак - person Sarah Tattersall; 02.01.2013

Сигурни ли сте, че атрибутите на модела са зададени правилно преди save? Дори нито един от неговите атрибути да не е зададен, той все още може да премине validate (в зависимост от това как е дефинирана функцията validate). Моля, опитайте да отпечатате модела в конзолата, за да проверите това. Между другото, по-добре е да подадете null вместо {} в save, по този начин методът set на модела няма да бъде извикан.

Актуализирано:

Според изходния код на Backbone, ако се подаде null като първи аргумент на save, атрибутите на модела ще се запазят непокътнати, докато моделът не бъде запазен на сървъра успешно. Така че другата възможност е вашият сървър да е успял да запази модела, но е върнал повреден обект, което води до повреда в метода set на модела. Ако все още не можете да разрешите проблема, проследяването на метода model.set може да помогне.

person Hui Zheng    schedule 30.12.2012
comment
Добавих дневник на модела преди във въпроса си, за да го видите. Също така промяната на {} на null изглежда не помага, но ще го променя в моя режим за по-добри практики - person Sarah Tattersall; 30.12.2012
comment
@SarahTattersall Току-що актуализирах отговора си, моля, проверете дали това помага. - person Hui Zheng; 30.12.2012
comment
Това е PUT заявка, така че отговарям с head :no_content в моя Rails контролер. Вместо това опитах respond_with @student, но изглежда, че и това не го коригира? Също така съм малко съмнителен относно отговора с ученик, когато това е PUT заявка? - person Sarah Tattersall; 30.12.2012
comment
@SarahTattersall Ако сте подали null или {} в save, отговорността на сървъра е да отговори на обект с всички актуализирани атрибути. След това Backbone ще извика model.parse(response, xhr) (по подразбиране това само връща изпратения отговор) и ще използва върнатата стойност, за да зададе атрибутите на модела. Вашият проблем може да бъде решен, ако сървърът върне подходящ JSON обект. Между другото, напълно разумно е да се отговори на студентски обект в PUT заявка. - person Hui Zheng; 30.12.2012
comment
@SarahTattersall Ако все още не можете да коригирате проблема, проследяването на метода model.set може да помогне. - person Hui Zheng; 30.12.2012
comment
Дори отговорът с JSON версия на студента изглежда не го коригира. Ще проуча комплекта, ако е възможно - person Sarah Tattersall; 30.12.2012