Я следую шаблону презентатора / декоратора, где у меня есть отдельный класс-обертка для записи, который добавляет дополнительные функции, такие как атрибуты форматирования и т. Д. *
Мои докладчики также обертывают атрибуты в span
тег с уникальной ссылкой DOM ID:
<span data-behavior="user_1_full_name">John Smith</span>
Это позволяет мне динамически обновлять атрибут с помощью JavaScript без обновления всей страницы.Обратите внимание, что я использую data-behavior
, потому что ID and CLASS
следует оставить для стилизации IMO CSS и избежать конфликтов.
User < ApplicationRecord
validates :first_name, presence: true
validates :last_name, presence: true
end
UserPresenter < SimpleDelegator
def initialize(record, view_context = nil)
@record = record
@view_context = view_context
end
# Iterate over this to dynamically update
def attributes_to_update
[:full_name, :first_name, :last_name].freeze
end
# ie, "John Smith"
def full_name
text = [@record.first_name, @record.last_name].join(" ")
attribute_wrapper(:full_name, text)
end
private
# Wraps attributes in unique data-behavior wrapper:
# ie: <span data-behavior="user_1_full_name">John Smith</span>
def attribute_wrapper(attribute, value)
@view_context.content_tag :span, value, data: { behavior: "#{dom_id(@record)}_#{attribute}".strip }
end
end
Это работает, и я могу динамически обновлять атрибуты с помощью JavaScript, используяэти data-behavior
атрибуты.
Однако у меня есть модель, которая имеет более 30 из этих атрибутов.Докладчик хранит массив атрибутов для обновления, поэтому я могу обновить их в файле вида js.erb
с несколькими строками кода:
# app/views/users/update.js.erb with jQuery
<%= @user_presenter.attributes_to_update.each do |attribute| %>
$("[data-behavior='user_<%= @user.id %>_<%= attribute %>]").replaceWith("<%=j @user.public_send(attribute) %>");
<% end %>
Проблема в том, что когда я просто обновляю одно поле, он обновит все 30+ из них.Помимо использования полнофункциональной интерфейсной среды, такой как React, есть ли чистый способ обновлять только измененные атрибуты?
Я в порядке с использованием vanilla JS или любых решений StimulusJS или даже небольших библиотек,но я не пытаюсь написать все на входной стороне.