2014-11-04 3 views
0

В моем приложении rails, похоже, что все файлы .js.coffee загружаются на каждую страницу, несмотря ни на что. Проблема, с которой я столкнулся, заключается в том, что файл places.js.coffee загружается, а затем возвращает нулевое значение внутри функции, потому что таблица, которую ищет файл locations.js.coffee, не существует ни на одной другой странице, которая а не на странице местоположений.Как предотвратить неправильный файл .js.coffee от загрузки

Примечание: в каждом из файлов: users.js.coffee, locations.js.coffee и campaigns.js.coffee Я разместил строки, соответственно, console.log («users.coffee загружен»), console.log («locations.coffee загружен») и console.log («campaigns.coffee загружен»), чтобы увидеть, если они загружены

Например, освежающие расположение страницы дает успешный вывод на консоль:

enter image description here

Но попытка попасть на страницу пользователей или кампаний будет пытаться загрузить файл locations.js.coffee, но так как таблицы, locatrions.js.coffee зависит с идентификатором #restaurantLocations не существует пользователей или кампаний, в результате ошибки:

enter image description here

Для линии: table.columns().eq(0).each (colIdx) в файле location.js.coffee.

Как предотвратить эту ошибку или разрешить загрузку правильного файла для правильной страницы и предотвратить загрузку других?

(Оставшийся locations.js.coffee код):

jQuery -> 
    console.log("locations.coffee loaded") 

    # Setup - add a text input to each footer cell 
    $("#restaurantLocations tfoot th").each -> 
    title = $("#restaurantLocations thead th").eq($(this).index()).text() 
    $(this).html "<input type=\"text\" placeholder=\"Search " + title + "\" />" 

    # DataTable 
    table = $("#restaurantLocations").DataTable() 

    # Apply the search 
    table.columns().eq(0).each (colIdx) -> 
    $("input", table.column(colIdx).footer()).on "keyup change", -> 
     table.column(colIdx).search(@value).draw() 

    # Hiding the id column, but for use for data manipulation 
    table.column(0).visible(false) 

    # Allowing multi-select 
    $("#restaurantLocations tbody").on "click", "tr", -> 
    $(this).toggleClass "selected" 

    # Allowing deletion (works) 
    $("#deleteLocations").click -> 
    multiSelected = table.rows(".selected").data() 
    table.rows(".selected").remove().draw false 
    for locationSelected in multiSelected 
     id = locationSelected[0] 
     $.ajax({ 
     url: "/locations/" + id,  # Note: $.ajax setup works as setting /locations/(id number) will allow deletion 
     type: "post", 
     dataType: "json", 
     data: {"_method":"delete"} 
     }) 

    # Conditional 'Select All' (works) 
    $("#selectAllLocations").click -> 
    table.$('tr', {"filter":"applied"}).addClass "selected" 

    # Deselecting all (works) 
    $("#deSelectAllLocations").click -> 
    table.$("tr").removeClass "selected" 

ответ

1

По умолчанию, Rails включает в себя файл на app/assets/javascripts/application.js, который требует все остальные файлы в app/assets/javascripts. Затем макет приложения по умолчанию включает этот файл.

Существуют и другие способы организации ваших активов, в том числе controller-specific assets. Они требуют настройки конфигурации ваших активов.

Однако я не рекомендую это делать. Гораздо лучше, если вы можете написать свой JavaScript таким образом, чтобы он мог быть включен на каждую страницу и просто ничего не выполнял на страницах, где он не нужен.

Существует много способов сделать это: одним простым является использование jQuery для поиска определенного класса на теле страницы или в другом месте на странице.

В приведенном выше коде все, что вам нужно сделать, это обернуть if $("#restaurantLocations").length > 0 вокруг всего объекта (но внутри функции обратного вызова jQuery).

Это дает несколько преимуществ:

  • Это более простой конфигурации, торчащие с конвенциями по умолчанию Rails, и легче понять.
  • Он более устойчив к изменениям в вашем приложении. Если вам нужно использовать этот JavaScript на новой странице или остановить его на существующей странице, вам нужно только добавить или удалить соответствующий класс (или любую разметку, которую вы ищете), а не суетиться с вашими тегами скрипта или требуются заявления в вашем активе.
  • Это позволяет избежать дублирования. Если сценарии на разных страницах имеют общие зависимости, вам необходимо будет потребовать их в обоих сценариях верхнего уровня.
  • Это лучше для пользователей, поскольку после того, как активы предварительно скомпилированы, вы получите один сжатый и сжатый файл, используемый на каждой странице вашего приложения. Пользователям нужно будет только один раз загрузить этот файл, а затем, перейдя на другие страницы, он будет загружен из кеша. Если не существует большого количества JavaScript, которые ограничены страницами, которые большинство пользователей никогда не посещают, более эффективно комбинировать все.

Прочитать The Asset Pipeline Rails Guide для получения информации о том, как активы работают в Rails.

+0

Единственное, что я бы добавил к этому ответу, это то, что если вы делаете это с помощью гигантской функции document.ready, вы, вероятно, ошибаетесь. +1 –

Смежные вопросы