Para meu entendimento, todo o seu JavaScript é mesclado em um arquivo. O Rails faz isso por padrão quando adicionado //= require_tree .
à parte inferior do seu application.js
arquivo de manifesto.
Isso soa como um salva-vidas real, mas estou um pouco preocupado com o código JavaScript específico da página. Esse código é executado em todas as páginas? A última coisa que quero é que todos os meus objetos sejam instanciados para todas as páginas quando forem necessários apenas em uma página.
Além disso, não há potencial para códigos que colidem também?
Ou você coloca uma pequena script
tag na parte inferior da página que apenas chama um método que executa o código javascript para a página?
Você não precisa mais do require.js?
obrigado
EDIT : Agradeço todas as respostas ... e não acho que elas estejam realmente entendendo o problema. Alguns deles são sobre estilo e não parecem se relacionar ... e outros apenas mencionam javascript_include_tag
... o que eu sei que existe (obviamente ...), mas parece que o caminho a seguir do Rails 3.1 é encerrar tudo seu JavaScript em um arquivo, em vez de carregar o JavaScript individual na parte inferior de cada página.
A melhor solução que posso encontrar é agrupar certos recursos em div
tags com id
s ou class
es. No código JavaScript, você apenas verifica se o id
ou class
está na página e, se estiver, executa o código JavaScript associado a ele. Dessa forma, se o elemento dinâmico não estiver na página, o código JavaScript não será executado - mesmo que tenha sido incluído no enorme application.js
arquivo compactado pelo Sprockets.
Minha solução acima tem o benefício de que, se uma caixa de pesquisa for incluída em 8 das 100 páginas, ela será executada apenas nessas 8 páginas. Você também não precisará incluir o mesmo código em 8 das páginas do site. Na verdade, você nunca mais precisará incluir tags de script manuais em seu site.
Eu acho que essa é a resposta real para minha pergunta.
fonte
application.js
), e na verdade a referência que você forneceu indica por que é assim: o download é o parte mais lenta do processo de execução do JS. Muitos arquivos pequenos têm mais cache do que um arquivo grande. O pessoal do Unholy Rails parece não perceber, então, que suas recomendações são inconsistentes com os princípios que estão tentando aderir e, portanto, suas recomendações não devem ser levadas a sério.Respostas:
Os documentos do Pipeline de ativos sugerem como executar JS específico do controlador:
Link para: asset_pipeline
fonte
page_specific_js = "#{params[:controller]}_#{params[:action]}"
e depois;javascript_include_tag page_specific_js if Rails.application.assets.find_asset page_specific_js
Para os js específicos da página, você pode usar a solução Garber-Irish .
Portanto, sua pasta javascripts do Rails pode ser assim para dois controladores - carros e usuários:
E javascripts ficará assim:
e markup_based_js_execution conterão código para o objeto UTIL e na execução do UTIL.init pronto para DOM.
E não esqueça de colocar isso no seu arquivo de layout:
Eu também acho que é melhor usar classes em vez de
data-*
atributos, para um melhor CSS específico da página. Como Jason Garber mencionou: os seletores de CSS específicos da página podem ficar muito estranhos (quando você usadata-*
atributos)Eu espero que isso te ajude.
fonte
window.varForOneController='val'
nesta função init do controlador. Também o gon gem pode ajudar aqui ( github.com/gazay/gon ). Pode haver outras soluções alternativas.//= require_tree .
e usar o JavaScript específico da página. Se você está tentando ativamente não fazer isso, está se esforçando para praticar mal.Vejo que você respondeu sua própria pergunta, mas aqui está outra opção:
Basicamente, você está assumindo que
É necessário. Não é. Sinta-se livre para removê-lo. No meu aplicativo atual, o primeiro que estou fazendo com o 3.1.x, honestamente, criei três arquivos JS de nível superior diferentes. Meu
application.js
arquivo tem apenasDessa forma, posso criar subdiretórios, com seus próprios arquivos JS de nível superior, que incluem apenas o que eu preciso.
As chaves são:
require_tree
- o Rails permite alterar as suposições feitasapplication.js
- qualquer arquivo noassets/javascript
subdiretório pode incluir diretivas de pré-processador com//=
Espero que ajude e adicione alguns detalhes à resposta do ClosureCowboy.
Sujal
fonte
//= require_tree .
por//= require_directory .
para manter todos os arquivos existentes onde estão e criar novos diretórios para arquivos específicos da página.Outra opção: para criar arquivos específicos de página ou modelo, você pode criar diretórios dentro de sua
assets/javascripts/
pasta.Seu
application.js
arquivo de manifesto principal pode ser configurado para carregar seus arquivosglobal/
. Páginas ou grupos de páginas específicos podem ter seus próprios manifestos, que carregam arquivos de seus próprios diretórios específicos. O Sprockets combinará automaticamente os arquivos carregadosapplication.js
com os arquivos específicos da página, o que permite que esta solução funcione.Essa técnica também pode ser usada
style_sheets/
.fonte
Agradeço todas as respostas ... e não acho que elas estejam realmente entendendo o problema. Alguns deles são sobre estilo e não parecem se relacionar ... e outros apenas mencionam
javascript_include_tag
... o que eu sei que existe (obviamente ...), mas parece que o caminho a seguir do Rails 3.1 é encerrar todos seu Javascript em um arquivo, em vez de carregar o Javascript individual na parte inferior de cada página.A melhor solução que posso encontrar é agrupar certos recursos em
div
tags comid
s ouclass
es. No código javascript. Em seguida, basta verificar se oid
ouclass
está na página e, se estiver, você executa o código javascript associado a ele. Dessa forma, se o elemento dinâmico não estiver na página, o código javascript não será executado - mesmo que tenha sido incluído no enormeapplication.js
arquivo compactado pelo Sprockets.Minha solução acima tem o benefício de que, se uma caixa de pesquisa for incluída em 8 das 100 páginas, ela será executada apenas nessas 8 páginas. Você também não precisará incluir o mesmo código em 8 das páginas do site. Na verdade, você nunca precisará incluir tags de script manuais em seu site em nenhum outro lugar - exceto para talvez pré-carregar dados.
Eu acho que essa é a resposta real para minha pergunta.
fonte
<script>
tags manuais . Sim, classes e IDs fazem parte da resposta, mas não faz sentido para o usuário carregar JavaScript que essa página específica não exige.Percebo que estou chegando a esta festa um pouco tarde, mas queria lançar uma solução que tenho usado ultimamente. No entanto, deixe-me mencionar primeiro ...
The Rails 3.1 / 3.2 Way (Não, senhor. Eu não gosto disso.)
Consulte: http://guides.rubyonrails.org/asset_pipeline.html#how-to-use-the-asset-pipeline
Estou incluindo o seguinte por uma questão de integridade nesta resposta, e porque não é uma solução inviável ... embora eu não me importe muito com isso.
O "Rails Way" é uma solução orientada a controladores, em vez de ser orientada a visualizações, conforme solicitado pelo autor original desta pergunta. Existem arquivos JS específicos do controlador com o nome de seus respectivos controladores. Todos esses arquivos são colocados em uma árvore de pastas que NÃO é incluída por padrão em nenhum aplicativo.js requer diretivas.
Para incluir código específico do controlador, o seguinte é adicionado a uma exibição.
Eu detesto essa solução, mas está lá e é rápida. Presumivelmente, você poderia chamar esses arquivos de algo como "people-index.js" e "people-show.js" e depois usar algo como
"#{params[:controller]}-index"
para obter uma solução orientada a exibição. Mais uma vez, solução rápida, mas não fica bem comigo.Maneira do meu atributo de dados
Chame-me de louco, mas quero TODO o meu JS compilado e compactado no application.js quando implantar. Não quero me lembrar de incluir esses pequenos arquivos dispersos em todo o lugar.
Carrego todo o meu JS em um arquivo compacto e em breve em cache do navegador. Se uma certa parte do meu application.js precisar ser acionada em uma página, deixo o HTML informar, não o Rails.
Em vez de bloquear meu JS para IDs de elementos específicos ou desarrumar meu HTML com classes de marcadores, eu uso um atributo de dados personalizado chamado
data-jstags
.Em cada página, eu uso - insira aqui o método preferido da biblioteca JS - para executar o código quando o DOM terminar de carregar. Esse código de inicialização executa as seguintes ações:
data-jstag
Digamos que eu tenha o seguinte definido em algum lugar no meu application.js:
O evento de auto-inicialização aplicará as funções
my_autosuggest_init
emy_hint_init
à entrada de pesquisa, transformando-a em uma entrada que exibe uma lista de sugestões enquanto o usuário digita, além de fornecer algum tipo de dica de entrada quando a entrada é deixada em branco e sem foco.A menos que algum elemento seja marcado
data-jstag="auto-suggest"
, o código de sugestão automática nunca é acionado. No entanto, ele está sempre lá, minificado e, eventualmente, armazenado em cache no meu application.js nos momentos em que eu preciso dele em uma página.Se você precisar passar parâmetros adicionais para as funções JS marcadas, precisará aplicar alguma criatividade. Adicione atributos de parâmetro de dados, crie algum tipo de sintaxe de parâmetro ou use uma abordagem híbrida.
Mesmo que eu tenha algum fluxo de trabalho complicado que pareça específico do controlador, apenas crio um arquivo para ele na minha pasta lib, empacoto-o em application.js e o identifico com algo como 'assistente de coisa nova'. Quando meu bootstrap atingir essa tag, meu assistente bonito e sofisticado será instanciado e executado. É executado para a (s) visualização (ões) desse controlador quando necessário, mas não está acoplado ao controlador. De fato, se eu codificar meu assistente corretamente, talvez seja possível fornecer todos os dados de configuração nas visualizações e, portanto, reutilizá-lo posteriormente para qualquer outro controlador que precise dele.
De qualquer forma, é assim que implemento o JS específico da página há algum tempo e isso me serviu bem tanto para designs de sites simples quanto para aplicativos mais complexos / ricos. Espero que uma das duas soluções que apresentei aqui, do meu jeito ou do Rails, seja útil para quem se deparar com essa questão no futuro.
fonte
Isso foi respondido e aceito há muito tempo, mas eu criei minha própria solução com base em algumas dessas respostas e na minha experiência com o Rails 3+.
O pipeline de ativos é bom. Use-o.
Primeiro, no seu
application.js
arquivo, remova//= require_tree.
Em seguida, no seu
application_controller.rb
método create a helper:Em seguida, no seu
application.html.erb
arquivo de layout, adicione seu novo auxiliar entre as inclusões javascript existentes, prefixadas com oraw
auxiliar:Agora, agora você pode criar facilmente javascript específico de exibição usando a mesma estrutura de arquivo usada em qualquer outro lugar nos trilhos. Basta colar seus arquivos
app/assets/:namespace/:controller/action.js.erb
!Espero que ajude alguém!
fonte
<%= raw ... %>
, retornará um 404?require_tree /
(ruim)?Você pode adicionar esta linha no seu arquivo de layout (por exemplo, application.html.erb) para carregar automaticamente o arquivo javascript específico do controlador (aquele que foi criado quando você gerou o controlador):
Você também pode adicionar uma linha para carregar automaticamente um arquivo de script por ação.
Basta colocar os scripts da página em um subdiretório nomeado após o nome do controlador. Nesses arquivos, você pode incluir outros scripts usando = require. Seria bom criar um auxiliar para incluir o arquivo apenas se ele existir, para evitar uma falha 404 no navegador.
fonte
fonte
Talvez você encontre a jóia pluggable_js como solução adequada.
fonte
A gema LoadJS é outra opção:
fonte
A resposta de Philip é muito boa. Aqui está o código para fazê-lo funcionar:
Em application.html.erb:
<body class="<%=params[:controller].parameterize%>">
Supondo que seu controlador se chame Projetos, isso gerará:
<body class="projects">
Em seguida, em projects.js.coffee:
fonte
<body>
é ipso facto incorreta. Veja meus comentários em outras partes desta página.Os JavaScripts são mesclados apenas quando você diz ao Rails (Sprockets, em vez disso) para mesclá-los.
fonte
//= require_tree .
?require_tree .
geralmente é uma má ideia.Foi assim que resolvi a questão do estilo: (desculpe o Haml)
Dessa forma, inicio todos os arquivos .css.sass específicos da página com:
Dessa forma, você pode evitar facilmente qualquer conflito. Quando se trata de arquivos .js.coffee, você pode apenas inicializar elementos como;
Espero que isso tenha ajudado alguns.
fonte
$('#post > #edit') ->
parece ser inválido. Como o escopo do jQuery funciona dentro de um escopo?= javascript_include_tag "application"
e= javascript_include_tag params[:controller]
dessa forma eu posso manter o código javascript confinado sem precisar especificar um escopo dentro do arquivo.Você também pode agrupar os js em pastas e continuar usando o pipeline de ativos para carregar seu javascript seletivamente, dependendo da página.
fonte
Concordo com sua resposta, para verificar se esse seletor está lá, use:
(não vi ninguém adicionar a solução real)
fonte
Não vejo uma resposta que realmente junte tudo e a exponha para você. Assim, tentarei colocar meleyal , sujal (à la ClosureCowboy ), a primeira parte da resposta de Ryan e até a ousada declaração de Gal sobre o Backbone.js ... todos juntos de uma maneira curta e clara. E, quem sabe, posso até atender aos requisitos de Marnen Laibow-Koser .
Edições de exemplo
assets / javascripts / application.js
visualizações / layouts / application.html.erb
visualizações / foo / index.html.erb
assets / javascripts / foo.js
assets / javascripts / foostuff / foothis.js . café
Descrição breve
Remova
//= require_tree .
do application.js e liste apenas o JS que cada página compartilha.As duas linhas mostradas acima em application.html.erb indicam à página onde incluir application.js e seu JS específico da página.
As três linhas mostradas acima em index.html.erb informam sua visualização para procurar por JS específico da página e incluí-lo em uma região de rendimento nomeada chamada ": javascript" (ou o que você quiser nomear). Neste exemplo, o controlador é "foo", portanto o Rails tentará incluir "foo.js" na região de rendimento: javascript no layout do aplicativo.
Liste sua JS específica da página em foo.js (ou qualquer que seja o nome do controlador). Liste bibliotecas comuns, uma árvore, diretórios, o que for.
Mantenha seu JS específico da página personalizado em algum lugar onde você possa referenciá-lo facilmente, além dos outros JS personalizados. Neste exemplo, o foo.js requer a árvore do foostuff; portanto, coloque seu JS personalizado lá, como foothis.js.coffee .
Não há regras rígidas aqui. Sinta-se à vontade para mover as coisas e, talvez, até criar várias regiões de rendimento de vários nomes em vários layouts, se necessário. Isso apenas mostra um possível primeiro passo à frente. (Eu não faço exatamente dessa maneira, considerando o uso do Backbone.js. Também posso optar por colocar o foo.js em uma pasta chamada foo, em vez de foostuff, mas ainda não decidimos isso.)
Notas
Você pode fazer coisas semelhantes com CSS,
<%= stylesheet_link_tag params[:controller] %>
mas isso está além do escopo da questão.Se eu perdi uma prática recomendada flagrante aqui, envie-me uma nota e eu vou me adaptar. O Rails é relativamente novo para mim e, sinceramente, não estou muito impressionado até agora com o caos que ele traz por padrão para o desenvolvimento empresarial e todo o tráfego que o programa Rails médio gera.
fonte
Tenho outra solução, que apesar de primitiva funcionar bem para mim e não precisar de nenhuma estratégia de carregamento seletivo sofisticada. Coloque sua função pronta para documento nornal, mas teste a localização atual do Windows para ver se é a página para a qual seu javascript se destina:
Isso ainda permite que todos os js sejam carregados pelo Rails 3.x em um pacote pequeno, mas não gera muita sobrecarga ou conflito com páginas para as quais os js não se destinam.
fonte
A resposta de ryguy é uma boa resposta, mesmo que tenha sido votada em pontos negativos.
Especialmente se você estiver usando algo como Backbone JS - cada página tem sua própria exibição de Backbone. Em seguida, o arquivo erb possui apenas uma única linha de javascript embutido que dispara a classe de exibição do backbone certo. Considero uma única linha de 'código de cola' e, portanto, o fato de que sua linha está correta. A vantagem é que você pode manter seu "require_tree", que permite ao navegador armazenar em cache todo o javascript.
em show.html.erb, você terá algo como:
e no seu arquivo de layout, você precisará de:
fonte
Mova todos os seus arquivos JS comuns para uma subpasta como 'app / assets / javascript / global' e, em application.js, modifique a
//= require_tree .
linha para//= require_tree ./global
.Agora você pode colocar seu JS específico do controlador na raiz 'app / assets / javascript /' e eles não serão incluídos no JS compilado, sendo usados apenas quando você os chamar
= javascript_include_tag
no seu controlador / visualização.fonte
Embora você tenha várias respostas aqui, acho que sua edição é provavelmente a melhor aposta. Um padrão de design que usamos em nossa equipe que recebemos do Gitlab é o padrão Dispatcher. Faz algo semelhante ao que você está falando, no entanto, o nome da página é definido na tag body pelos trilhos. Por exemplo, no seu arquivo de layout, inclua algo como (em HAML):
Então, tenha apenas um encerramento e uma instrução switch no seu
dispatcher.js.coffee
arquivo na pasta javascripts da seguinte maneira:Tudo o que você precisa fazer nos arquivos individuais (digamos
products.js.coffee
oulogin.js.coffee
por exemplo) é incluí-los em uma classe e globalizar esse símbolo de classe para que você possa acessá-lo no expedidor:O Gitlab tem vários exemplos disso com os quais você pode querer bisbilhotar caso esteja curioso :)
fonte
Paloma projeto oferece uma abordagem interessante para gerenciar o código javascript específico da página.
Exemplo de uso de seus documentos:
fonte
Passo 1. remover require_tree. em seu application.js e application.css.
Passo 2. Edite seu application.html.erb (por padrão do Rails) na pasta de layout. Adicione "params [: controller]" nas seguintes tags.
Etapa 3. Adicione um arquivo em config / initializers / assets.rb
referências: http://theflyingdeveloper.com/controller-specific-assets-with-rails-4/
fonte
Eu não tentei isso, mas parece que o seguinte é verdade:
se você tiver um content_for que é javascript (por exemplo, com javascript real dentro dele), as rodas dentadas não saberiam disso e, portanto, isso funcionaria da mesma maneira que agora.
se você deseja excluir um arquivo do grande pacote de javascript, você deve entrar no arquivo config / sprockets.yml e modificar os arquivos de origem de acordo. Em seguida, inclua qualquer arquivo excluído, quando necessário.
fonte
Eu fiz isso anteriormente usando este método: http://theflyingdeveloper.com/controller-specific-assets-with-rails-4/ . Super fácil, confia nos controladores para selecionar os js adequados a serem carregados.
fonte
Eu combinei algumas respostas em:
Auxiliar de aplicação:
layouts / application.html.haml:
fonte
Primeiro: remove
\\=require_tree
from application.js Segundo: todo o seu código JS deve ser alocado em/app/assets/javascritpt
e todo o seu código CSS deve ser alocado em/app/assets/stylesheets
fonte
Seguindo a liderança de Ryan, aqui está o que eu fiz:
application.js.coffee
users.js.coffee (coffeescript específico do controlador, por exemplo, controller: users, action: dashboard)
application.html.haml
fonte
eval
) se o seu HTML for comprometido por um servidor quebrado ou por um script de usuário mal-intencionado.Veja como fazer isso, especialmente se você não precisar executar toneladas de bibliotecas para sua página específica, mas apenas executar algumas centenas de linhas de JS mais ou menos.
Como é perfeitamente adequado incorporar o código Javascript no HTML, basta criar no diretório app / views shared.js e colocar lá o código específico da sua página / páginas em my_cool_partial.html.erb
Então agora, de onde você quiser, basta:
E é isso, k?
fonte