Состояние базовой линии при привязке к форме

Я создаю форму с Backbone и хочу проверить ее поля на событии "размытие".

Вступление в мероприятие достаточно простое, но мне интересно, нужно ли обновлять модель на размытие или только при отправке формы?

Обновление модели при размытии

  • model.set({...}, {validate:true});
  • Если ваша модель имеет несколько атрибутов, проверка будет выполняться для всех из них, каждый раз
  • при создании нового элемента состояние модели не так важно, потому что оно, вероятно, не используется совместно с другими модулями
  • при редактировании элемента модель находится в этом странном устаревшем/обновленном состоянии, в зависимости от того, где человек находится в форме. Что делать, если модель разделяется между несколькими модулями?

Обновление модели при отправке

  • не может использовать model.set() для проверки, поэтому модели необходимо выставить некоторые методы проверки (например, MyModel.validZip())
  • on submit, хотя все поля были проверены, необходимо вызвать функцию set() для обновления модели, что приведет к повторной проверке проверки (не совсем уверен, что это плохо).

Я прочитал пару релевантных проблем github Backbone (1, 2, 3), и разработчики Backbone, похоже, рисуют линию между моделью и формой.

Кроме того, плагин Backbone.Form, похоже, сохраняет внутреннее свойство fields для отслеживания полей формы и когда это делается, вызовите .commit() для обновления модели.

Таким образом, кажется, что обновление модели на submit - лучший подход. Это тот опыт, который у вас был?

Ответ 1

Собственный UX в формах сложный. Я пробовал оба ваших подхода в прошлом. На мой взгляд, существует третий вариант: всегда поддерживать синхронизацию модели с состоянием вашего представления.

В этом коротком видео выделяются некоторые из моих рассуждений: http://screencast.com/t/qukIe6XW5.

В этом видео я печатаю форму. Автообновление формы показывает, сколько символов я набрал и сколько разрешено. Это хороший UX для обеспечения мгновенной обратной связи, а не для того, чтобы пользователь удалял фокус из формы, обнаруживал, что у них есть ошибки проверки, а затем возвращается к форме. Чтобы достичь этого, вам нужно будет всегда знать состояние своего вида.

Но я не хочу, чтобы мое состояние модели обновлялось автоматически! Пользователь сначала должен нажать submit!

Похоже, что введение другого класса моделей сделает вашу жизнь намного проще. Подумайте о создании модели представления, в которой содержится ссылка на экземпляр вашей модели. С введением viewmodel вы сможете записывать изменения в свое представление, не влияя на состояние вашей модели. Это помогает снизить риск возникновения плохих вещей, и, если что-то пойдет наперекосяк, ваш сервер сможет поймать изменения и потерпеть неудачу с проверкой на стороне сервера.

Вот некоторые ссылки на мой источник для редактирования на месте:

Вы увидите, что я даю EditPlaylistPromptView модель EditPlaylistPrompt, в которой хранится ссылка на редактируемый плейлист. Однако он не модифицирует этот плейлист напрямую, пока пользователь работает над представлением. Он просто обновляет список воспроизведения, как только он проходит проверку. Обратите внимание, что я не просматриваю модель для проверки, но я мог бы просто расслабить ее в этом аспекте.

Вот картина того, как мне нравится визуализировать вещи. Совершенно верно, что модель должна быть заинтересована в том, чтобы обеспечить разделение проблем. Однако, только тогда, когда вы работаете с 3 слоями объектов. Будьте более гибкими, представите новый, промежуточный слой, называемый ViewModel, и ваша жизнь станет проще:

enter image description here

Ответ 2

Обновление модели на представлении похоже на лучший подход. Магистраль - это структура MVC (более MV *, но предназначена для соблюдения тех же принципов). При этом все точки контроллеров должны иметь отдельный уровень, предназначенный для ограничения или контроля того, как пользователь взаимодействует с данными (моделью). Таким образом, только позволяя пользователю обновлять модель до тех пор, пока все не будет корректно соответствовать традиционной логике MVC.

Кроме того, вы только проверяете, как пользователь подал заявку и по существу сказал: "Это то, что я хочу, чтобы вещи были". Обновление по размытию может превентивно проверить информацию.

См. wikipedia MVC: "[MVC] делит данное программное приложение на три взаимосвязанные части, чтобы отделить внутренние представления информации от способов представления информации или принято пользователем"

Ответ 3

Это зависит от того, как вы хотите, чтобы пользователи взаимодействовали с вашим приложением. Если вы хотите, чтобы события всегда были в синхронизации (например, в документах Google), вы могли обновить модель на "change", а затем отправить в фоновый код на "размытие" или с некоторым определенным временным интервалом.

Если вы хотите, чтобы пользователи нажимали кнопку "Отправить", было бы лучше не обновлять модель до тех пор, пока вы не будете готовы отправить данные в исходный код.

Ответ 4

Я могу только сказать по своему опыту, и это, очевидно, будет очень упрямым.

Мне не нравится на самом деле устанавливать значения на модели, не спрашивая сначала сервер, является ли изменение значения достаточным для того, чтобы оно было передано, и, следовательно, для всех модулей, отображающих или в зависимости от модели объект в вопросе. Очень возможно, что вход не будет принят сервером, хотя он прошел все условия, на которые клиент мог проверить (например, действительный адрес электронной почты, но не уникальный на сервере). При этом часть ввода должна и может быть немедленно подтверждена без предварительного запроса на бэкэнд. В конце концов, это, вероятно, будет "лучшим из обоих миров". Честная мудрость, я знаю;).

Самое главное здесь - возможность вернуться к предыдущему действительному состоянию, независимо от того, какая часть процесса вызвала недействительность. Я имею в виду это странное устаревшее/обновленное состояние, о котором вы говорили выше. Мы можем абсолютно быть уверены в правильности изменения, если "компьютер говорит" да "(бэкэнд, то есть).

Теперь, как этого достичь? Здесь два подхода (предварительное условие для обоих примеров: все объекты модели имеют уникальный атрибут идентификатора, и если мы не говорим "create" ):

Измените временный объект, зеркало на фактический объект, если он проверяет.

  • Пусть форма представляет новый объект модели, независимо от того, говорим ли мы о "обновлении" или "создании". Вы можете отличить их, запросив идентификатор позже:

    // update
    var tempModel = new MyModel(modelToUpdate.serialize());
    // or create
    var tempModel = new MyModel();
    
  • set и/или submit значения объекта в зависимости от пользовательского опыта, который вы хотите предоставить. У меня был бы процесс проверки как можно более общий и всегда проверяющий объект (каждая пара ключей/значений) в целом. Подробнее об этом чуть позже.

  • В случае действительного (и полного) процесса изменения зеркалируйте изменения обратно к вашему фактическому объекту модели или создайте новый:

    var model;
    if (tempModel.isValid() === false) {
        // report Error
    } else if (tempModel.get('id')) {
        model = modelToUpdate.set(tempModel.serialize()).save();
    } else {
        model = tempModel.save();
        // do what you got to do with a new model object
    }
    
  • Основные минусы: пока вы не отслеживаете временно созданный объект модели, другие части приложения не будут знать о предстоящих изменениях.

Сохранять текущее состояние во временном объекте, вернуться к его состоянию, если проверка не завершена.

  • Сохраните текущее и, надеюсь, действительное состояние объекта модели до того, как начнется процесс модификации:

    var currentlyValid = new MyModel(modelToUpdate.serialize());
    
  • set и/или submit фактический объект по своему усмотрению. Вы должны снова не заботиться о конкретных парах ключ/значение, но убедитесь, что весь объект действителен. Главное преимущество в том, что другие части приложения в зависимости от и/или отображения объекта, о котором идет речь, будут синхронизироваться. Основной недостаток: вы должны обрабатывать создание новых предметов отдельно.

  • Заблудиться во временном объекте, если изменения будут проверены. Если нет, откат назад в ранее сохраненное состояние.

    if (modelToUpdate.isValid()) {
        var currentlyValid = null;
        modelToUpdate.save();
    } else {
        modelToUpdate.set(currentlyValid.serialize());
    }
    
  • Основной вывод: я не могу думать об упрощенном способе создания новых объектов с помощью этого подхода. Зависит от реализации, я думаю.

Я предпочитаю первый подход. Если речь идет о синхронизации других частей вашего приложения, которые должны отображать изменения на объекте модели с текущим временным объектом на размытии, можно было бы создать объект модели приложения, обладающий свойством, которое указывает на последнем и запускает изменения событий всякий раз, когда изменяется временный объект:

var app = MyApplication({
    modelThatIsGettingModified: <Reference to the temp object>; 
});

Почему мы не используем previousAttributes для отката?

Поскольку каждый вызов set, который прошел проверку на стороне клиента, изменит возврат этого свойства модели, независимо от того, был ли весь объект подтвержден сервером или нет.

Слово о проверке

Учитывая тот факт, что метод проверки на базовых моделях...

... остается undefined, и вам рекомендуется переопределить его с вашей пользовательской логикой проверки, если у вас есть все, что может быть выполненный в JavaScript... (источник Backbone docs)

... Я предлагаю вам всегда проверять все пары ключей/значений. Это может вызвать определенные накладные расходы, но это позволит вам унифицировать процесс проверки. Я очень хорошо знаю 1, 2 и 3, но, честно говоря, такие вещи вряд ли замедлят ваше приложение, пока вы держите DOM под контролем. Здесь более важен процесс упрощенного валидации. Если эти виды увольнений начинают влиять на производительность вашей вещи, вы, вероятно, не должны использовать Backbone вообще IMHO.