С Meteor, почему DOM-манипуляция НИКОГДА не должна выполняться с помощью jQuery?

Мне интересно, насколько корректно это утверждение:

Хорошим правилом является то, что если вы используете jQuery для управления любыми элементами DOM, вы, вероятно, ошибаетесь.

из ответа на этот вопрос: Meteor - Как передать данные между помощниками и событиями для шаблона?

Как я вижу, jQuery хорош, потому что он может быть хирургическим и манипулировать многими небольшими частями DOM без необходимости изменять весь блок кода.

Шаблоны в Meteor великолепны, потому что именно то, что они делают, - они могут заменять целые блоки кода или небольшие крошечные вещи для чего-то другого, но при дорогостоящем определении его явно каждый раз и переопределении кода, который на самом деле не изменение.

Пример. В фокусе jQuery удаляет класс idleField, добавляет класс focusField и меняет местозаполнитель на другой текст:

$('input[type="text"]').focus(function() {
 $(this).removeClass("idleField").addClass("focusField").attr("placeholder", "First Name NOW");
});

Результат

jQuery является коротким и сладким и предназначен только для переключения класса и заполнителя.

Но с шаблонами Meteor тот же результат будет выглядеть примерно так:

Session.set('toggleClassEditPlaceholderSessionVar', ' class="idleField" id="first_name" name="firstName" type="text" placeholder="First Name" ');
Template.form.helpers({
 toggleClassAndEditPlaceholder: function() {
 return Session.get('toggleClassEditPlaceholderSessionVar');
)};
Template.form.events({
 'focus input[type="text"]': function () {
 Session.set('toggleClassEditPlaceholderSessionVar', ' class="focusField" id="first_name" name="firstName" type="text" placeholder="First Name NOW" ');
 }
});

Метод Meteor намного более подробный и, по крайней мере, в этом примере включает избыточные элементы (id, name и type не изменяются, только класс и placeholder). jQuery предназначался ТОЛЬКО классу и заполнителю и оставил все остальное в одиночестве. Тем не менее, шаблоны иногда должны охватывать множество посторонних вещей. В этом примере, конечно, я мог бы переместить местозаполнитель и класс бок о бок в моем коде, чтобы идентификаторы, имя и тип были не затронуты при определении шаблона, но в другом коде вы бы не смогли.

Так что я делаю неправильно? Должен ли быть более эффективный способ сделать это в Meteor, более эффективном, чем только одна строка jQuery?

2 ответа

Заявление, о котором идет речь, было сделано девять месяцев назад. Это было очень важно в то время. С тех пор двигатель Meteor UI получил полный пересмотр. Одним из ключевых моментов этого изменения было сделать двигатель более дружественным JQuery. Раньше, когда вы меняли с помощью JQuery, вероятность того, что Meteor вернет это изменение при перерисовке. Теперь он делает свои изменения гораздо более умным способом, поэтому безопасно изменять состояние элементов с помощью чистого JQuery.

Это, как говорится, по-прежнему хорошая практика тщательно подумать, действительно ли изменение, которое вам понадобится, действительно сделано с помощью JQuery. В частности, лучше оставить все связанные с данным изменениями в "Метеор". Однако в вашем случае вы изменяете поведение компонента пользовательского интерфейса, основываясь исключительно на его состоянии. Поэтому, чтобы сделать это изменение только с помощью Meteor, вам нужно создать объект искусственных данных, и в самом деле, лучше использовать JQuery в этом случае.

 

 

Кроме того, ваш код Метеор может быть значительно улучшен. Вам не нужно передавать все атрибуты тега в помощнике, это достаточно, чтобы изменить то, что вам нужно:

Template.form.helpers({
 class: function() {
 return Session.get('toggled') ? 'focusField' : 'idleField';
 },
 placeholder: function() {
 return Session.get('toggled') ? 'focusPlaceholder' : 'idlePlaceholder';
 },
)};
Template.form.events({
 'focus input[type="text"]': function () {
 Session.set('toggled', true);
 },
});


Во-первых, исходная публикация SO, которую вы цитируете, ссылалась на использование jQuery для "реактивных" изменений данных (по данным модели), и ответ указывал автору на использование API Collection, чтобы избежать необходимости вручную обновлять DOM. Когда вы извлекаете данные из Meteor.Collection и отображаете их на странице, вы используете "реактивный" источник данных... обновления будут выполняться автоматически.

Ваш пример действительно не соответствует тем же соображениям. Таким образом, вы бы определенно использовали jQuery для упрощения вашего подхода. Это выглядело бы так:

Template.form.events({
 'focus input[type="text"]': function (e) {
 $(e.currentTarget).removeClass("idleField").addClass("focusField").attr("placeholder", "First Name NOW");
 }
});

Нет причин помешать глобальному объекту Session с помощью пары пар ключ/значение для атрибутов элемента. Даже если вы это сделали, нет причин хранить атрибуты, которые остаются теми же (id, name, type).

licensed under cc by-sa 3.0 with attribution.