как передавать данные с помощью javascript в rails [duplicate]

Предположим, что у вас есть следующий код

fruits = ("apples", "bananas", "loganberries")

def eat(food=fruits):
    ...

Когда я вижу декларацию о еде, наименее удивительной является мысль, что если первый параметр не указан, он будет равен tuple ("apples", "bananas", "loganberries")

Однако, предположим позже в коде, я делаю что-то вроде

def some_random_function():
    global fruits
    fruits = ("blueberries", "mangos")

, тогда, если параметры по умолчанию были связаны с выполнением функции, а не с объявлением функции, тогда я бы удивляйтесь (очень плохо), чтобы обнаружить, что фрукты были изменены. Это было бы более удивительно ИМО, чем обнаружение того, что ваша функция foo, указанная выше, мутировала список.

Реальная проблема заключается в изменяемых переменных, и все языки имеют определенную проблему. Возникает вопрос: предположим, что в Java у меня есть следующий код:

StringBuffer s = new StringBuffer("Hello World!");
Map<StringBuffer,Integer> counts = new HashMap<StringBuffer,Integer>();
counts.put(s, 5);
s.append("!!!!");
System.out.println( counts.get(s) );  // does this work?

Теперь, использует ли моя карта значение ключа StringBuffer, когда оно было помещено на карту, или оно хранит ключ по ссылке? В любом случае, кто-то удивлен; либо человек, который попытался получить объект из Map, используя значение, идентичное тому, с которым он положил его, или человек, который, похоже, не может получить свой объект, даже если ключ, который они используют, буквально тот же объект, который использовался для размещения его на карте (на самом деле Python не позволяет использовать его изменяемые встроенные типы данных в качестве словарных клавиш).

Ваш пример хороший случая, когда новички Python будут удивлены и укушены. Но я бы сказал, что если бы мы «исправили» это, тогда это создало бы другую ситуацию, в которой они были бы укушены, и это было бы еще менее интуитивным. Более того, это всегда имеет место при работе с изменяемыми переменными; вы всегда сталкиваетесь с ситуациями, когда кто-то может интуитивно ожидать одно или наоборот поведения в зависимости от того, какой код они пишут.

Мне лично нравится текущий подход Python: аргументы функции по умолчанию оцениваются, когда функция определена, и что объект всегда является значением по умолчанию. Я предполагаю, что они могут использовать специальный случай с пустым списком, но такой специальный корпус вызовет еще большее удивление, не говоря уже о несовместимости в обратном направлении.

37
задан Safa Alai 15 December 2011 в 03:11
поделиться

6 ответов

Вы можете редактировать и добавлять переменные в массив params в контроллере, а затем обращаться к ним в response.js.erb. Вот пример с params[:value]:

def vote
  value = params[:type] == "up" ? 1 : -1
  params[:value] = value
  @public_comment = PublicComment.find(params[:id])

  have_voted = @public_comment.evaluators_for(:pub_votes_up) << @public_comment.evaluators_for(:pub_votes_down)

  unless have_voted.include?(@current_user) # vote
    @public_comment.add_or_update_evaluation(:"pub_votes_#{params[:type]}", value, @current_user)
  else                                      # unvote
    @public_comment.delete_evaluation(:"pub_votes_#{params[:type]}", @current_user)
    params[:value] = 0
  end

  respond_to do |format|
    format.js # vote.js.erb
  end
end

И вот пример, сопровождающий response.js.erb

button = $('<%= ".pub#{params[:type]}_#{params[:id]}" %>')
label = button.find('strong')
<% comment = PublicComment.find(params[:id]) %>
label.html('<%= comment.reputation_for(:"pub_votes_#{params[:type]}").to_i %>')

<% if params[:value] == 1 %>
  button.addClass('btn-success')
<% elsif params[:value] == -1 %>
  button.addClass('btn-danger')
<% else %>
  if button.hasClass('btn-success') { button.removeClass('btn-success') }
  if button.hasClass('btn-danger') { button.removeClass('btn-danger') }
<% end %>
0
ответ дан Archonic 21 August 2018 в 13:38
поделиться

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

<div class="searchResults" data-query="<%= @q %>"></div>

, затем jquery для доступа к нему

url: "/search/get_results?search[q]=" + $(".searchResults").data("query") + "&page=" + p

Я считаю, что это самый чистый способ передачи данных на javascript. Не нашел способа передать переменную в файл сценария кофе с конвейером ресурсов рельсов с контроллера. Это метод, который я сейчас использую. Не могу дождаться, пока кто-то установит путь контроллера с рельсами, которые будут лучшими.

5
ответ дан Dave Robertson 21 August 2018 в 13:38
поделиться

несколько способов, которые я сделал в прошлом

, помещают данные в скрытые поля, получают доступ к данным в js / coffee

# single value
<%= hidden_field_tag "foo_name", @foo.name, { :id => "foo-name" } %>
$('#foo-name').val();

# when the 'value' has multiple attributes
<%= hidden_field_tag "foo", @foo.id, { :id => "foo", "data-first-name" => @foo.first_name, "data-last-name" => @foo.last_name } %>
$foo = $('#foo')
console.log $foo.val()
console.log $foo.data("firstName")
console.log $foo.data("lastName")

другой опции: загружать данные в js-структуру данных в erb, получить доступ к ней из js / coffee

<% content_for(:head) do %>
    <script>
    window.App = window.App || {};
    window.App.Data = window.App.Data || {};
    window.App.Data.fooList = [
        <% @list.each do |foo| %>
            <%= foo.to_json %>,
        <% end %>
    ];
    </script>
<% end %>


# coffee
for foo in window.App.Data.fooList
    console.log "#{foo.id}, #{foo.first_name} #{foo.last_name}"

Я не большой поклонник создания javascript-данных из ruby ​​в erb, как это, что-то об этом просто кажется неправильным - это может быть хотя

и еще один вариант: сделать ajax-вызов и получить данные по запросу с сервера

. Меня также интересуют другие идеи и подходы

27
ответ дан house9 21 August 2018 в 13:38
поделиться
  • 1
    Если вам нужно запустить циклы и построить json, вы можете использовать файл before_filter, который запускает метод для создания одного объекта JSON и присваивает ему переменную экземпляра. Затем вы просто выставляете одну переменную экземпляра в своем представлении Javascript. Я нахожу это лучше, чем ajax, потому что это один меньше HTTP-запросов. – BradGreens 25 June 2013 в 20:27
  • 2
    Второй вариант выглядит очень хорошо. Имейте это в виду. – Donato 12 May 2016 в 23:20

В этой конкретной теме есть отличная рельсовая передача и довольно недавняя (февраль 2012): # 324 Передача данных на JavaScript

Это показывает три способа: сценарий тег, атрибут данных и камень Gon. Я думаю, что дом покрыл все доступные методы. Я бы сказал только, что использование вызова AJAX лучше всего использовать, когда у вас большой объем данных, динамические данные или их комбинация.

8
ответ дан Max 21 August 2018 в 13:38
поделиться
  • 1
    Не могли бы вы добавить примерный код к вашему ответу? – rudolph9 29 July 2013 в 23:33
  • 2
    Рудольф, откройте RailsCast, а также примеры кода. Лучшие примеры, чем я мог когда-либо дать :) – Max 30 July 2013 в 11:02
  • 3
    Я открывал, я видел, но ответы должны быть автономными со всем подходящим примером кода (т. Е. not требуют доступа к другой странице, чтобы получить соответствующую информацию) ... – rudolph9 30 July 2013 в 23:27
  • 4
    Указанные технологии те же, что и для передачи переменных в Js в представлениях: stackoverflow.com/questions/2464966/… – Ciro Santilli 新疆改造中心 六四事件 法轮功 6 October 2014 в 13:23
  • 5
    Это был лучший ответ. Я добавил ответ, который включал примеры с использованием gon, но мой рейтинг одобрения для редактирования был настолько низким, что я просто переписал его как ответ. – Ninjaxor 18 February 2015 в 17:31

В контроллере:

@foo_attr = { "data-foo-1" => 1, "data-foo-2" => 2 }

В представлении (HAML):

#foo{@foo_attr}

В ресурсе CoffeeScript:

$("#foo").data("foo-1")
$("#foo").data("foo-2")
3
ответ дан michau 21 August 2018 в 13:38
поделиться

В ситуациях, когда ваши данные javascript выходят из-под контроля, использование gon gem по-прежнему является предпочтительным способом перехода на рельсы, даже в 2015 году. После настройки gon вы можете передавать данные в файлы javascript, просто присваивая данные для объекта gon в рельсах.

(Gemfile)
gem 'gon'

(controller) 
def index 
  gon.products = Product.all 

(layouts) 
<%= include_gon %> 

(public/javascripts/your_js_can_be_here.js) 
alert(gon.products[0]['id'); 

(html source automatically produced) 
<script> 
  window.gon = {}; 
  gon.products = [{"created_at":"2015", "updated_at":"2015, "id":1, "etc":"etc"}];

Вы можете прочитать более подробные детали реализации на Gon или два других канала rails-javascript из скринкаста Райана Бате. http://railscasts.com/episodes/324-passing-data-to-javascript

1
ответ дан Ninjaxor 21 August 2018 в 13:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: