4

Я пробовал 4 года, чтобы выяснить, как я могу использовать карты Google в своем приложении Rails.Rails - выяснение конфигурации javascript

Я попытался использовать gmaps4rails, но отказался, потому что это слишком сложно. Мне удалось найти решение на SO, которое работало, за исключением того, что я не мог указать уровень масштабирования. Однако в производстве все мои другие javascripts не работали. Решением для этого было переместить:

<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> 

из тега головы и нижней части тега тела.

Это работает, чтобы все мои другие файлы js работали так же, как в среде разработки, но в режиме производства теперь карта вообще не будет отображаться.

Есть ли решение, которое:

  1. позволяет мне использовать мои JavaScript файлы (кроме карты JS файла Google) - я думаю, это достигается тем, что в JavaScript включает тег в конце корпус вместо головы

  2. позволяет мне отображать карту google на производстве? Если я переведу тег javascript include в голову, я смогу отобразить карту, но остальные мои файлы js не работают (только в производстве).

  3. позволяет мне указать уровень масштабирования на моей карте?

Я пытался обратиться за помощью here, here и here (и миллион других времен на этой плате). Мне еще не удалось найти помощь.

В моем address.js, у меня есть:

function initMap() { 
    var map = new google.maps.Map(document.getElementById('map'), { 
    zoom: 5 
    }); 
    var bounds = new google.maps.LatLngBounds(); 
    // var opts = { 
    // zoom: 10, 
    // max_zoom: 16 
    // } 

    var n = addresses.length; 
    for (var i = 0; i < n; i++) { 
    var lat = addresses[i].latitude; 
    var lng = addresses[i].longitude; 
    if (lat == null || lng ==null){ 
     console.log(addresses[i].name + " doesn't have coordinates"); 
    }else { 
     var address = new google.maps.Marker({ 
     position: {lat: parseFloat(lat), lng: parseFloat(lng)}, 
     title: addresses[i].name, 
     map: map //, 
//  zoom: 8 
     }); 
     bounds.extend(address.position); 
    } 
    } 
    map.fitBounds(bounds); 
} 

Как я изложил в этой post, я получаю ошибку, которая говорит:

initMap is not a function 

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

Что касается уровня масштабирования на карте, ответ в this post объясняет эту проблему как относящуюся к js, запрашивающую карту с каждым адресом в ней. Это каким-то образом заставляет уровень масштабирования быть максимально увеличенным, независимо от уровня, который я пытаюсь указать. Таким образом, есть 2 проблемы, первый - как удалить бит, который заставляет наиболее увеличивать уровень, чтобы я мог установить уровень масштабирования, который будет подтвержден, а второй - вне зависимости от того, было ли какое-то изменение в способе выражения увеличения потому что так много ответов на SO (включая те, которые были связаны в моем сообщении) предлагают использовать «setZoom» вместо «zoom: 5». Я не могу найти решение, которое сработало.

Как я описал в this post, файлы js (за исключением карт Google) не работают в производстве, если у меня есть тег javascript include в голове. Я только пришел к этому решению после долгого дорогого сеанса на кодовом языке. Я не могу позволить себе другую сессию, чтобы узнать, как решить проблемы, которые это решение создало. Я также не получил объяснений относительно фундаментальной причины, почему это изменение необходимо. Руководства по рельсам предлагают включить его там, поэтому я не понимаю, почему, по большей части, перемещение его до конца тега тела - это решение, которое заставляет js работать в производственной среде.Это ломает адрес JS, хотя, так что это не является правильным решение

В моем config.rb меня

config/initializers/assets.rb 

# Be sure to restart your server when you modify this file. 
# Version of your assets, change this if you want to expire all your assets. 
Rails.application.config.assets.version = '1.0' 

# Add additional assets to the asset load path 
# Rails.application.config.assets.paths << Emoji.images_path 

# Precompile additional assets. 
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 
# Rails.application.config.assets.precompile += %w(search.js) 
config/production.rb 

    # Do not fallback to assets pipeline if a precompiled asset is missed. 
    config.assets.compile = false 

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

Если это имеет значение, моя производственная среда находится на геройку. Любые советы, которые касаются соответствующих принципов, будут очень оценены - если прямой ответ не сразу станет очевидным.

ПРИНИМАТЬ R_G'S ПРЕДЛОЖЕНИЕ

Я изменил свой файл address.js включить новую первую строку и новую последнюю строку. Этот файл теперь:

;(function ready() { 
function initMap() { 
    var map = new google.maps.Map(document.getElementById('map'), { 
    zoom: 5 
    }); 
    var bounds = new google.maps.LatLngBounds(); 
    // var opts = { 
    // zoom: 10, 
    // max_zoom: 16 
    // } 

    var n = addresses.length; 
    for (var i = 0; i < n; i++) { 
    var lat = addresses[i].latitude; 
    var lng = addresses[i].longitude; 
    if (lat == null || lng ==null){ 
     console.log(addresses[i].name + " doesn't have coordinates"); 
    }else { 
     var address = new google.maps.Marker({ 
     position: {lat: parseFloat(lat), lng: parseFloat(lng)}, 
     title: addresses[i].name, 
     map: map //, 
//  zoom: 8 
     }); 
     bounds.extend(address.position); 
    } 
    } 
    map.fitBounds(bounds); 
} 
})(); 

При запуске сервера и попытаться отобразить страницу, карта еще не делает (только пустое белое пространство, где оно должно быть). В инспекторе хрома отсутствуют ошибки консоли (так же, как нет, когда я не использую первую и последнюю строки, предложенные R_G).

РЕАКЦИЯ ENGINEER DAVE В ответ на вопросы:

Q1: Является ли ваши производственные активы, прекомпилирован?

Нет - причина в том, что мои заметки о производстве.rb не говорят мне об этом. Смотрите здесь:

# Do not fallback to assets pipeline if a precompiled asset is missed. 
    config.assets.compile = true 

    # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb 

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

В asset.rb, ноты говорят:

# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.# Do not fallback to assets pipeline if a precompiled asset is missed. 

Я понимаю, что это значит, вся перечисленные в application.js уже обработано таким образом, нет никакой необходимости для дальнейших шагов перекомпиляции. Я понимаю (из предыдущих попыток на протяжении многих лет решить эту проблему, которая удваивается при компиляции, является причиной отдельного набора проблем).

Мой файл address.js указан в файле application.js (через дерево require), поэтому он должен обрабатываться любым процессом, который использует asset.rb.

Q2. Вам требуется дерево в application.js

Да. Я.

На ваш комментарий: «Также, если вам не требуется полное дерево файлов JS в application.js, файлы, помеченные вами для предварительной компиляции в assets.rb, например address.js, будут предварительно скомпилированы, но не загружается."

Моего application.js имеет:

//= require jquery 
//= require jquery_ujs 
//= require turbolinks 
//= require jquery-fileupload/vendor/jquery.ui.widget 
//= require jquery-fileupload/jquery.iframe-transport 
//= require jquery-fileupload/jquery.fileupload 
//= require bootstrap-sprockets 
//= require moment 
//= require bootstrap-datetimepicker 
//= require pickers 
// require underscore 
// require gmaps/google 
//= require markerclusterer 
//= require cocoon 
//= require cable 
//= require_tree . 

Я требует дерева Address.js в моей папке приложения/активов/JavaScripts поэтому он должен быть подобран require_tree линии в конце. список в application.js

Я не уверен, что понял какой-либо из ваших комментариев. Есть ли предположение, что я могу попытаться заставить это работать? Является ли ваше предложение игнорировать инструкции в assets.rb и production.rb setup?

В чем разница b между «предварительно скомпилированными» и «загруженными»? Я попытаюсь провести некоторое исследование, чтобы понять, что это значит сейчас. КОММЕНТАРИЙ

ENGINEERDAVE на R_G'S внушения

EngineerDave предлагает со ссылкой на this post в качестве потенциального решения. Это сообщение говорит:

  1. перемещение JavaScript включает тег в конец моего тела тега (который я сделал, с эффектом, что карта Google больше не работает, но скрыть/показать JS в другом файле, теперь не работает).

  2. используя следующую строку:

    document.addEventListener ("DOMContentLoaded", функция (событие) {// работают });

Это сообщение идет предложить более простую реализацию этой линии, как:

фактической рабочей равнине Javascript реализация здесь, если кто-то хочет код они могут просто упасть в: stackoverflow.com/вопросы/9899372/... - jfriend00 13 декабря '14 в 7:58

That link, предлагает:

<script> 
// self executing function here 
(function() { 
    // your page initialization code here 
    // the DOM will be available here 

})(); 
</script> 

Мой текущий код в address.js начинается с этой строки:

function initMap() { 

Принимая предложение в этой должности, я стараюсь замещающего эту линию:

(function() { 
    function initMap() { 
    //then continue with the rest of my address.js file 
})(); 

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

DOWNVOTE

Я не понимаю причину вниз голосования по этому вопросу. Я много лет пытаюсь научиться работать с рельсами с помощью javascript. Я потратил тысячи долларов на codementor.io/ upwork и кучу других сайтов, которые пытаются заплатить за профессиональную помощь, чтобы узнать это. Я был в каждой встрече в своем городе и предлагаю попробовать их в разных городах, когда у меня есть возможность сделать это.Я не нашел человека, который смог понять это. 4+ года, и я все еще пытаюсь решить это. В чем причина этого. Это не дает мне представления о том, почему этот форум не подходит для поиска помощи. У меня нет вариантов альтернатив. У меня просто нет никакого бюджета, чтобы тратить деньги на codementor.io. Снижение голосов ограничивает меня только тем, что замедляет меня от возможности начать еще одну щедрость на этом форуме, чтобы попытаться найти некоторую информацию, которая поможет решить эту проблему. Если у вас есть конструктивная обратная связь о том, как лучше задавать этот вопрос или делать исследования, необходимые для поиска ответа, - это было бы с благодарностью оценено. Хорошего дня.

Для всех остальных, спасибо, что пытались мне помочь.

BRENZY'S SUGGESTION

Спасибо, что нашли время, чтобы сделать репо. Это так полезно, если кто-то еще это объяснит. Тем не менее, это не работает для меня. Мне пришлось адаптировать некоторые из ваших подходов, чтобы избавиться от некоторых ошибок, которые это сделало для меня. Я установил, как я включил ваше предложение и ошибка это дает ниже:

Application.html.erb

Изменение:

  1. Я переехал в Javascript включает тег обратно в head tag

  2. Над ярлыком js include я разместил ссылку источника google. Я показал ссылку, которую вы предложили в комментарии ниже, и ссылку, которую я использовал под ней. Мне пришлось изменить ссылку, потому что у меня возникла ошибка, говорящая о каких-либо ключах API, использующих вашу ссылку.

    <%= csrf_meta_tags %> 
    <%= favicon_link_tag %> 
    <!-- <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script> --> 
    <script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV["GOOGLE_MAPS_API_KEY"] %>"async defer></script> 
    
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> 
    <!-- Latest compiled and minified CSS --> 
    <%= stylesheet_link_tag href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css" %> 
    
    <!-- Optional theme --> 
    <%= stylesheet_link_tag href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap-theme.min.css" %> 
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> 
    

приложение/активы/JavaScripts/initialise.js

Я сделал новый файл - как ваш.

function initialize() { 
    var losAngeles = new google.maps.LatLng(34.0500, -118.2500); 
    var pasadena = new google.maps.LatLng(34.14778, -118.14452); 
    var mapOptions = { 
    zoom: 10, 
    center: losAngeles, 
    disableDefaultUI: true, 
    mapTypeControlOptions: google.maps.MapTypeId.SATELLITE 
    }; 
    map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions); 
} 

google.maps.event.addDomListener(window, 'load', initialize); 

Текущая ошибка указывает на последнюю строку этого файла.

Одна вещь, которую я не понимаю из вашего комментария, заключается в том, что вы считаете, что этот файл находится за пределами конвейера активов. Я не понимаю, потому что ваш application.js имеет require_tree, который, как я понимаю, означает, что все в app/assets/javascripts включено в конвейер.

мой взгляд сейчас же, как ваша:

<div id="map-canvas"></div> 

Когда я сохраняю все это и попробовать его, я получаю сообщение об ошибке, которое говорит:

Uncaught ReferenceError: google is not defined 
    at initialize.self-f919dc6….js?body=1:13 
(anonymous) @ initialize.self-f919dc6….js?body=1:13 

Существует только пустой белый вместо карты.

большая проблема

Я толкнул это Heroku и попытался серийную версию. Теперь js, который скрывает &, показывает, что поля формы на основе других вариантов формы не работают. Это была оригинальная проблема, которая привела к включению тега javascript include в конец тела вместо основного тега.

Это Js находится в файле с именем приложения/активы/JavaScripts/позиция/commercial.js

jQuery(document).ready(function() { 
    jQuery('[name="organisation[commercial_attributes][standard_financial_split]"]').on('click', function() { 
     if (jQuery(this).val() == 'true') { 
      jQuery('#commercial_standard_financial_split_content').removeClass('hidden'); 
     } else { 
      jQuery('#commercial_standard_financial_split_content').removeClass('hidden').addClass('hidden'); 
     } 
    }); 

}); 

Это сделал работу, когда Javascript включает тег был перемещен в конец тела тега. Теперь, когда он вернулся в тег заголовка - он не работает.

+4

«Я боролся 4 года ...» Бро? –

+0

Мои первые попытки были в течение первых 3,5 лет - за это время я пытался выяснить, как использовать gmaps4rails в своем приложении. Слишком сложно учиться. Предполагается знание во всех учебниках, которые нигде не выражаются. Я сдался, пытаясь расшифровать его. Я нашел решение без этого драгоценного камня, но теперь я не могу заставить его работать, если мой js находится в конце тега body и в любом случае, я не могу получить уровень масштабирования для работы. – Mel

+0

Эй, там! Я уже работал с рельсами и gmaps, и все работает отлично, включая масштабирование. Я посмотрю на исходный код вечером. Если я не буду отвечать в течение 24 часов, пингуйте меня здесь. – unkmas

ответ

2

РЕДАКТИРОВАТЬ: см. Обновление в конце для более подробного объяснения, но я только что увидел, что является наиболее вероятной ошибкой. Если вы будете следовать моим рекомендациям, это, безусловно, поможет. Я предположил, что вы только вставляете одну функцию своего кода, а не весь свой файл. Важнее (в большинстве случаев) JavaScript, чтобы гарантировать, что вся страница загрузилась до того, как ваш код начнет работать. Это цель «функции() {...}», которую я рекомендовал. Он ожидает, пока документ не будет загружен до начала выполнения сценария. Без этого вы, скорее всего, увидите ложные ошибки в ваших сценариях, например, «initMap не является функцией». Следуйте моим рекомендациям и посмотрите, поможет ли это.


Вы уже могли бы делать это, так что дайте мне знать, если это правда, но ...

Если ваши результаты варьируются в зависимости от размещения в скриптах, моя мысль будет то, что вы загрязняющие глобальное пространство имен и страдание конфликтующих переменных. Гораздо безопаснее обернуть весь ваш код, чтобы его структура была локальной и не влияла на глобальную.

Pure JavaScript будет иметь этот шаблон:

;(function() { 
    // Document is ready here 
})(); 

Я использую JQuery, и поэтому я делаю это так:

;$(function ($, window, document) { 
    // Document ready here 
}(window.jQuery, window, document)); 

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

Эй, это хотя бы стоит того.


ОБНОВЛЕНИЕ: Поскольку вы спросили, и я передал вам первое предложение, позвольте мне разобрать это для вас. Используемый код:

;(function() { 
    // Document is ready here 
})(); 

Замените «// Документ готов сюда» с вашим текущим кодом. Если у вас есть несколько файлов, содержащих ваш текущий код, сделайте то же самое для каждого.

Первая точка с запятой только для того, чтобы прервать любой предыдущий код, если они забыли его прекратить. Скобка после точки с запятой является ключом к локальной изоляции. Он соединяется с первой скобкой в ​​последней строке. Любые переменные или функции, которые вы определяете в этих скобках, будут изолированы от чего-либо вне их. Последние две спаренные скобки в последней строке выполняют весь код как функцию, поэтому создавая ваш внутренний код. Без этого ваш код будет недоступен.

+0

Это не место в разных сценариях. Здесь помещается тег include, который, похоже, влияет на приложение js – Mel

+0

@Mel Да, тег include «Возвращает тег HTML-скрипта для каждого из предоставленных источников». При перемещении он меняет места расположения указанных источников по отношению к остальной части файла. В любом случае, избегая загрязнения глобальной окружающей среды, это рекомендуемая модель и, на мой взгляд, стоит того. YMMV. –

+0

Я не знаю, как попробовать ваше предложение. Начальная строка моего address.js: function initMap() { Вы предлагаете добавить «; $» в начало строки открытия? и добавьте «($, window, document) в конец строки открытия, а затем« (window.jQuery, window, document) »? Я пробовал это, но он дает синтаксическую ошибку, которую я не знаю, как отлаживать я не понимаю его конструкцию. – Mel

1

Я создал чрезвычайно простое приложение Rails 5 в https://github.com/brenzy/sample1, которое загружает карту google как в dev, так и в производственных средах.

1) Я добавил Google Maps сценария вне трубопровода активов и убедился, что это было выше application.js включает:

<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>

2) В соответствии с EngineerDave, я использовал следующую строку убедитесь, что карта не инициализируется до ее загрузки.

google.maps.event.addDomListener(window, 'load', initialize); 

Я не касался каких-либо настроек конфигурации по умолчанию.

Надеюсь, это будет соответствовать тому, что вам нужно, и вы можете сравнить его с тем, что делает ваш код.

+0

Привет @brenzy Большое спасибо за создание репо. Я попробовал ваше предложение и изложил попытку в конце поста выше. К сожалению, он не работал для рендеринга карты, но также разбивает другие js (другие js работают, когда тег javascript include находится в конце тега body, а не тег head). – Mel

+0

@Mel - Извините, что это не сработало для вас. Если я запустил код в репо, я вижу карту. Если это была моя проблема, я бы начал с нуля, просто отображая карту без бутстрапа и без каких-либо css. Если вы добавите назад компоненты javascript по одному, это может дать вам представление о том, где находится несовместимость. Не имеет смысла, что Google не определен, если initialize вызывается только из google.maps.event.addDomListener. Я также хотел бы добавить некоторые инструкции console.log, чтобы узнать, откуда исходит ошибка, а также выполнить пошаговый код. – brenzy

+0

Большое спасибо за предложение. Боюсь, я не знаю, что искать в качестве индикаторов несовместимости. Я проработал курс javascript для школьной школы примерно 3 раза, но это не очень хорошо для того, чтобы попытаться выяснить эти проблемы. Я сделал новое приложение около 6 месяцев назад, чтобы попытаться решить эту конкретную проблему, но я всего лишь потратил 6 месяцев на то, чтобы переместить строки в разные порядки, чтобы увидеть, поможет ли угадать, когда я наткнусь на ответ. Полагаю, я продолжу этот подход. Большое вам спасибо за то, что нашли время, чтобы сделать это репо. Я ценю усилия. – Mel

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

  • Нет связанных вопросов^_^