#ruby-on-rails #twitter-bootstrap #modal-dialog
#ruby-on-rails #twitter-bootstrap #модальный диалог
Вопрос:
Когда я нажимаю на представление в модальном режиме, оно продолжает отображать только первую запись. Даже если я нажму на вторую запись, она все равно отобразит первую. Ниже показано, как я реализовал link_to переключение на модальное поле под названием myModal.
<%= link_to 'View in Modal', "#", data: {toggle: "modal", target: "#myModal"} %>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">amp;times;</button>
<h4 class="modal-title" id="myModalLabel">Test</h4>
</div>
<div class="modal-body">
<span class="note"><%= raw(usernote.note) %></span>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
Ответ №1:
Проблема
Я предположил, что вы сделали что-то вроде:
<% @usernotes.each do |usernote| %>
<%= link_to ... %>
// code of modal associated to the usernote
<% end %>
Проблема в том, что вы использовали один и тот же идентификатор html для всех модалов ( #myModal
) . Помимо того, что дублирование идентификаторов не соответствует W3C, это является причиной проблемы.
Когда вы нажмете на одну из ссылок, откроется первая модальная с #myModal
идентификатором (который является модальным для первой записи).
Итак, как исправить проблему?
Простой способ: один модальный на заметку пользователя
Один из способов, простой способ, — использовать разные идентификаторы для всех модалов. Например:
<%= link_to ... data: {toggle: "modal", target: "#modalForUserNote#{ usernote.id }"} %>
<div id="modalForUserNote<%= usernote.id %>" ...>
// ....
Но этот способ не самый лучший: вы просто создаете один модальный для каждой заметки пользователя… Если у вас 1000 пользовательских заметок, вы сгенерируете 1000 модалов в своем html… Это, очевидно, довольно плохо…
Другой способ: обратный вызов javascript
Другой способ сделать это — создать только один модальный файл и отредактировать его содержимое с помощью некоторого кода Javascript.
Примером кода может быть:
html code
// the modal code
<% @usernotes.each do |usernote| %>
<% link_to ..., data: {toggle: "modal", target: "#modal"}, 'data-usernoteid' => ..., 'data-usernotedata' => ... %>
<% end %>
javacript code (using jQuery)
$('.modalLink').on('click', function() {
$('#modal #idOfTheUserNote').html($(this).data('usernoteid'));
// ...
});
Вы можете отметить использование атрибутов данных.
Атрибуты данных могут быть заменены AJAX-запросом к вашему приложению Rails, который вернет данные JSON.
Другой способ: запрос AJAX
Последний способ сделать это — запросить ваше приложение Rails с помощью вызова Ajax. Ваше приложение отобразит представление Javascript (код будет отправлен в ваш браузер и оценен).
Это можно просто сделать, используя remote: true
опцию в вашем link_to (rails сам обработает запрос ajax.
Следующий код может сделать трюк:
html code
// the modal code
<% @usernotes.each do |usernote| %>
<% link_to 'text', some_action(usernote), data: {toggle: "modal", target: "#modal"}, remote: true %>
<% end %>
controller code
def some_action
@usernote = Usernote.find_by_id(param[:id])
end
view to render: for example usernote/some_action.js.erb
$("#modal #modalIdOfTheUsernote").html("<%= @usernoed.id %>");
Каков наилучший способ сделать это?
Очевидно, не первую.
Выбор между двумя другими зависит только от того, что вы хотите сделать:
- Для обновлений в реальном времени запрос AJAX может быть лучше. Но вы можете получить некоторую задержку, потому что вам нужно дождаться ответа сервера.
- В противном случае атрибуты данных достаточно хороши.
Комментарии:
1. Ответ может занять некоторое время… особенно, когда английский не является родным языком.
Ответ №2:
здесь 3 варианта:
- создайте один модальный для каждой записи — худшее, что вы можете сделать
- используйте атрибуты данных для обновления содержимого модального
- используйте действие ajax, в котором вы обновите содержимое модала и откроете модал с помощью
$('#myModal').modal('show')
http://getbootstrap.com/javascript/#modals-usage
1. создайте один модальный для каждой записи
<% @usernotes.each do |usernote| %>
<%= link_to 'View in Modal', "#", data: {toggle: "modal", target: "#myModal_<%= usernote.id %>"} %>
<div class="modal fade" id="myModal_<%= usernote.id %>" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
....
<span class="note"><%= raw(usernote.note) %></span>
....
</div>
<% end %>
2. используйте атрибуты данных для обновления содержимого модального
<% @usernotes.each do |usernote| %>
<%= link_to 'View in Modal', "#", data: {usernote: usernote.note}, class: 'user_note_modal' %>
<% end %>
$('.user_note_modal').on('click', function() {
$('#myModal span.note').html($(this).data('usernote'));
$('#myModal').modal('show');
});
p.s. зачем использовать .modal('show')
? просто убедитесь, что вы сначала обновили содержимое модала, а затем отобразили его.
3. используйте действие ajax — при условии, что ваше имя ресурса UserNote
и у вас есть user_notes_controller
с show
действием:
<% @usernotes.each do |usernote| %>
<%= link_to 'View in Modal', usernote_path(usernote), data: {toggle: "modal", target: "#myModal"}, remote: true %>
<% end %>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-body">
<span class="note"></span>
</div>
</div>
нажатие на одну ссылку вызовет событие ajax, которое будет ожидать шаблон show.js.erb, в котором вы обновите содержимое модала, а затем отобразите его:
app/views/user_notes/show.js.erb
$('.modal-body span.note').html('<%= j(render @usernote.note) %>');
$('#myModal_').modal('show');