Rails 5 / JavaScript: динамически обновлять только те атрибуты записи, которые были обновлены на странице - PullRequest
0 голосов
/ 05 июня 2018

Я следую шаблону презентатора / декоратора, где у меня есть отдельный класс-обертка для записи, который добавляет дополнительные функции, такие как атрибуты форматирования и т. Д. *

Мои докладчики также обертывают атрибуты в 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 или даже небольших библиотек,но я не пытаюсь написать все на входной стороне.

1 Ответ

0 голосов
/ 22 июля 2018

Решение 1

использовать небольшую виртуальную библиотеку DOM, такую ​​как HyperHTML.Это несколько других библиотек, таких как вы, вы можете Google их.Я использовал HyperHtml в прошлом, и он прекрасно работает

https://github.com/WebReflection/hyperHTML

Решение 2 Если вы используете Stimulus, вы можете отслеживать каждое значение поля исохраните их в атрибуте данных, используя API-интерфейс Stimulus data.set («field-name»).Это строка, поэтому, если вы хотите сохранить объект, вам нужно сначала его заформатировать.Затем обновляйте только поля, если значение изменилось.больше информации в документации Stilulus

https://stimulusjs.org/handbook/managing-state

...