Rails - descobrindo a configuração javascript

Estou lutando há 4 anos para descobrir como posso usar o google maps no meu aplicativo Rails.

Eu tentei usar o gmaps4rails, mas desisti porque é muito difícil. Eu consegui encontrar uma solução no SO, que funcionou, exceto que eu não conseguia especificar um nível de zoom. No entanto, na produção, todos os meus outros javascripts não funcionaram. A solução para isso foi mover o:

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

fora da etiqueta da cabeça e na parte inferior da etiqueta do corpo.

Isso funciona para permitir que todos os meus outros arquivos js operem como no ambiente de desenvolvimento, quando no modo de produção, no entanto, agora o mapa não será renderizado.

Existe uma solução que:

permite que eu use meus arquivos javascript (que não sejam o arquivo js do google maps) - o que eu acho que é conseguido com a tag javascript include no final do corpo, em vez da cabeça

me permite renderizar um mapa do google em produção? Se eu mover a tag de inclusão javascript de volta à cabeça, posso renderizar o mapa, mas o restante dos meus arquivos js não funcionará (somente em produção).

permite especificar um nível de zoom no meu mapa?

Eu tentei pedir ajudaaqui, aqui eaqui (e um milhão de outras vezes neste fórum). Ainda não consegui encontrar ajuda.

No meu address.js, tenho:

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);
}

Como descrevi nestepostar, Recebo um erro que diz:

initMap is not a function

Eu marquei todas as postagens relevantes que sugerem soluções nessa postagem vinculada, juntamente com os resultados de meus esforços para usá-las para resolver meu problema.

Em relação ao nível de zoom no mapa, a resposta emesta postagem explicou o problema como sendo atribuível aos js solicitando um mapa com cada endereço nele. De alguma forma, isso força o nível de zoom a ser o mais ampliado, independentemente do nível que eu tento especificar. Portanto, existem 2 problemas: o primeiro é como remover o bit que força o nível mais ampliado para que eu possa definir um nível de zoom que será reconhecido e o segundo é se houve alguma alteração na maneira de expressar o zoom nível, porque muitas respostas no SO (incluindo as que estão no meu post) sugerem o uso de "setZoom" em vez de "zoom: 5". Não consigo encontrar uma solução que funcionou.

Como descrevi emesta postagem, os arquivos js (exceto o google maps) não funcionarão em produção se eu tiver a tag de inclusão javascript na cabeça. Eu só cheguei nessa solução depois de uma longa e cara sessão no codementor. Não posso pagar outra sessão para descobrir como resolver os problemas que esta solução criou. Também não obtive uma explicação sobre a razão fundamental pela qual essa mudança é necessária. Os guias de trilhos sugerem incluí-lo lá, então eu não entendo por que, na maioria das vezes, movê-lo para o final da tag body é uma solução que faz com que os js funcionem no ambiente de produção. Isso quebra o endereço js, portanto, não é a solução certa

No meu config.rb eu tenho

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

Eu tentei cada uma das soluções postadas nas postagens vinculadas (que são principalmente de outras pessoas que postaram neste fórum. Gostaria muito de aprender o princípio envolvido em descobrir isso (para que eu possa começar a aprender a pensar da maneira que Estou impressionado com o fato de que isso é tão difícil e por que tão pouco é escrito sobre como configurar aplicativos para trabalhar em produção em qualquer um dos textos. Existe claramente um problema que precisa de uma solução (eu penteei os 100s de outras postagens sobre este tópico, mas não consegue encontrar uma resposta com princípios) ou uma solução que funcione.

Se isso faz alguma diferença, meu ambiente de produção está no heroku. Qualquer conselho, por princípios relevantes, seria muito apreciado - se uma resposta direta não for imediatamente aparente.

TOMANDO A SUGESTÃO DE R_G

Alterei meu arquivo address.js para incluir uma nova primeira linha e uma nova última linha. Esse arquivo agora tem:

;(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);
}
})();

Quando inicio o servidor e tento renderizar a página, o mapa ainda não é renderizado (apenas um espaço em branco vazio onde deveria estar). Não há erros de console aparecendo no inspetor chrome (da mesma forma que não ocorre quando não uso a primeira e a última linhas sugeridas por R_G).

RESPOSTA AO ENGENHEIRO DAVE Em resposta às suas perguntas:

Q1: seus ativos de produção estão sendo pré-compilados?

Não - a razão para isso é que minhas notas de production.rb me dizem para não. Veja aqui:

# 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

Entendo que essas notas significam que o assets.rb lida com a pré-compilação, portanto, não é mais necessário pré-compilar os ativos de produção. A primeira linha das instruções que eu copiei acima me diz para não voltar ao pipeline de ativos, então não tenho certeza do que você espera ver de maneira diferente.

No asset.rb, as notas dizem:

# 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.

Entendo que isso significa que tudo o que está listado no application.js já está sendo tratado, portanto não há necessidade de etapas adicionais de recompilação. Eu entendo (de tentativas anteriores ao longo dos anos para resolver esse problema, que dobrar a compilação é a causa de um conjunto separado de problemas).

Meu arquivo address.js está listado no meu arquivo application.js (por meio da árvore de solicitações), portanto, ele deve ser tratado por qualquer processo que o assets.rb use.

Q2 Você está exigindo a árvore no application.js

Sim. Eu sou.

Para o seu comentário: "Além disso, se você não estiver solicitando toda a árvore JS de arquivos no application.js, os arquivos que você sinalizou para pré-compilação no assets.rb, por exemplo, address.js, serão pré-compilados, mas não serão carregados . "

Meu application.js possui:

//= 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 .

Eu estou exigindo a árvore. Address.js está na minha pasta app / assets / javascripts, portanto deve ser selecionado pela linha require_tree no final da lista em application.js

Não tenho certeza se entendi algum comentário seu. Existe alguma sugestão de que eu possa tentar fazer isso funcionar? Sua sugestão é ignorar as instruções nas configurações assets.rb e production.rb?

Qual é a diferença entre 'pré-compilado' e 'carregado'? Vou tentar fazer alguma pesquisa para entender o que isso significa agora.

COMENTÁRIOS DA ENGINEERDAVE SOBRE A SUGESTÃO DE R_G

EngineerDave sugere referir-se aesta postagem como uma solução potencial. Este post sugere:

mover a tag javascript include para o final da tag body (o que fiz, com o efeito de que o mapa do google não funciona mais, mas ocultar / mostrar js no outro arquivo que não estava funcionando agora funciona).

usando esta linha:

document.addEventListener ("DOMContentLoaded", function (event) {// do trabalho});

Esse post sugere uma implementação mais simples dessa linha, como:

Uma implementação de javascript simples e funcional aqui, se alguém quiser código, pode simplesmente aparecer em: stackoverflow.com/questions/9899372/… - jfriend00 Dec 13 '14 at 7:58

Esse link, sugere:

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

})();
</script>

Meu código atual no address.js começa com esta linha:

function initMap() {

Tomando a sugestão deste post, tento substituir essa linha por:

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

Quando salvo e tento, obtenho o mesmo resultado de quando tentei a primeira sugestão de R_G. Nenhum mapa. Nenhum erro de console sendo exibido no inspetor chrome.

THE DOWNVOTE

Não entendo o motivo da baixa votação nesta questão. Estou lutando há anos para tentar aprender a trabalhar com trilhos com javascript. Eu gastei milhares de dólares em codementor.io/ upwork e vários outros sites tentando pagar por ajuda profissional para aprender isso. Estive em todos os encontros da minha cidade e faço questão de experimentá-los em diferentes cidades quando tiver a oportunidade de fazê-lo. Não encontrei uma pessoa capaz de descobrir isso. Mais de 4 anos e ainda estou tentando resolver isso. Qual é o motivo da baixa deste voto? Não me dá uma idéia do porquê deste fórum não é o lugar certo para procurar ajuda. Estou sem opções para alternativas. Só não tenho mais orçamento a perder no codementor.io. O voto negativo me custa apenas pontos, o que me impede de começar outra recompensa neste fórum para tentar encontrar algumas informações que ajudarão a resolver esse problema. Se você tiver um feedback construtivo sobre a melhor forma de fazer essa pergunta ou fazer a pesquisa necessária para encontrar a resposta - qualquer uma dessas coisas será apreciada com gratidão. Tenha um bom dia.

Para todos os outros, obrigado por tentar me ajudar.

SUGESTÃO DE BRENZY

Muito obrigado por reservar um tempo para fazer o repo. É muito útil ver alguém explicar isso. Dito isto, isso não funciona para mim. Tive que adaptar parte da sua abordagem para me livrar de alguns dos erros que isso me causou. Decidi como incorporei sua sugestão e o erro que ela fornece abaixo:

Application.html.erb

Alterar:

Mudei a tag de inclusão javascript de volta para a tag head

Acima da tag js include, coloquei o link da fonte do google. Eu mostrei o link que você sugeriu no comentário abaixo e o link que usei abaixo dele. Tive que alterar o link porque recebi um erro ao dizer que não havia chaves de API usando seu link.

<%= 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' %>

app / assets / javascripts / initialise.js

Criei um novo arquivo - como o seu.

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);

O erro atual está apontando para a última linha deste arquivo.

Uma coisa que não entendo nos seus comentários é que você acha que esse arquivo está fora do pipeline de ativos. Eu não entendo isso porque seu application.js possui require_tree, o que entendo como significando que tudo no app / assets / javascripts é incluído no pipeline.

Minha opinião agora é a mesma que a sua:

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

Quando guardo tudo isso e tento, recebo um erro que diz:

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

Há apenas um espaço em branco em branco em vez de um mapa.

O MAIOR PROBLEMA

Enviei isso para o heroku e tentei a versão de produção. Agora, o js que oculta e mostra os campos do formulário com base em outras seleções de formulário não funciona. Esse foi o problema original que levou à colocação da tag de inclusão javascript no final do corpo, em vez da tag head.

Esse js está em um arquivo chamado app / assets / javascripts / stance / 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');
      }
   });

});

Isso funcionou quando a tag de inclusão javascript foi movida para o final da tag do corpo. Agora que está de volta à tag head - não funciona.

questionAnswers(2)

yourAnswerToTheQuestion