У меня есть простой вид, который привязывает себя к перерисовке, когда модель изменяется, поскольку большинство направляющих указывают:
this.model.bind('change', this.render, this);
Этот вид имеет форму с полем ввода и кнопкой отправки. Я привязываюсь к событию "change" в поле ввода, чтобы изменить связанный элемент модели. (Я могу сделать это вручную или с проектом ModelBinder, работает одинаково в любом случае.)
Пользователь меняет значение в поле ввода формы, затем нажимает кнопку отправки. Модель обновляется, вид и форма повторно отображаются. Событие нажатия кнопки отправки распадается.
Я использую свойство Backbone events:
events : {
'submit form' : 'save'
},
Я знаю, что событие игнорируется, потому что элемент DOM, на который был нажат, больше не существует. Я могу поместить небольшой setTimeout внутри render(), чтобы предотвратить замену HTML, и все работает так, как ожидалось, но для этого требуется ожидание.
Я не могу быть первым человеком, который мог бы бороться с этим - какой стандартный способ захвата формы "изменить" события, обновить модель и перерисовать представление, не теряя при этом нажатия клавиш или нажатия клавиш?
Аналогично, если у меня есть несколько элементов формы, пользователь не может заносить вкладку между элементами после изменения содержимого по мере того, как форма перерисовывается.
Обновление 1 - 3 дня спустя
По-прежнему пытается найти хорошее решение. Вещи, которые я пробовал:
- перемещение или клонирование содержимого представления в другую область на странице. Событие клика по-прежнему никогда не принимается.
- регистрация события click с $(document).on или $(document).live вместо объекта стандартных событий представления
- отделяя форму так, чтобы вся форма (входы и кнопки) оставалась вместе, не перерисовываясь. Перерисовать родительские элементы (которые полагаются на значения формы) и повторно вставить уже нарисованную форму. Это устраняет связанную с этим проблему неспособности выполнить вкладку по элементу, но не фиксирует события щелчка.
- работает как угодно в firefox 4, но не ie9 или хром. *
Обновление 2 - с примером кода
Один из комментариев задал какой-то код. Я значительно упростил код на одной странице и включил его ниже. Фактическое приложение намного сложнее. С помощью кода, приведенного ниже, я мог бы просто вручную повторно отобразить части страницы при изменении. В фактическом приложении я использую шаблоны dustjs, и даже если я не повторно визуализую форму, но повторно переопределяю элементы, содержащие форму, на которую возникают проблемы, нажав на submit. Я надеюсь на "шаблон", который типичен для базовых приложений, включая сложные страницы, модели и формы.
Большинство "демонстрационных" приложений и даже сайтов, которые я видел с использованием магистральной сети, как правило, представляют собой приложения, ориентированные на презентацию, которые на самом деле не собирают много ввода от пользователя. Если вы знаете о хорошем приложении/демонстрации, ориентированном на сбор данных, на основе основы, которая была бы полезной.
код:
<!doctype html>
<html lang="en">
<head>
<script src="libs/jquery.js"></script>
<script src="libs/underscore.js"></script>
<script src="libs/backbone.js"></script>
</head>
<body>
<div id="container"></div>
<script type="text/template" id="edit_user_template">
<h3>Edit User <%=id%> : <%=name%></h3>
<form>
Name: <input type="text" name="name" value="<%=name%>"><br/>
Email: <input type="text" name="email" value="<%=email%>"><br/>
<input type="submit">
</form>
</script>
<script>
var UserModel = Backbone.Model.extend({});
var model = new UserModel({id: '1', name:'Joe', email:'[email protected]'});
var UserView = Backbone.View.extend({
events : {
'submit form' : 'save',
'change input' : 'inputChange'
},
initialize: function(){
this.model.bind('change', this.render, this);
},
render: function(){
var template = _.template($('#edit_user_template').html(), this.model.toJSON());
this.$el.html(template);
},
inputChange : function(evt){
var target = $(evt.currentTarget);
this.model.set(target.attr('name'), target.val());
},
save : function(event){
console.log('saving');
event.preventDefault();
//this.model.save();
}
});
var view = new UserView({model: model, el: '#container'});
view.render();
</script>
</body>
</html>