Как сделать на странице javascript с конвейером Rails
Я понимаю, что по соображениям производительности лучше разрешить конвейер конвейера и минимизировать весь мой javascript и отправить всю партию с каждым запросом страницы. Это достаточно справедливо
Однако, куча моего javascript - это нечто вроде привязки определенного поведения к конкретным элементам страницы - например,
$('button').click(function(e) { $('input.sel').val(this.name); }
и я чувствовал бы себя более комфортно, если бы знал, что этот код выполняется только на этой странице, а не на другой странице evey, которая по совпадению может иметь элементы с одинаковыми идентификаторами или которые соответствуют тем же селекторам. Как люди справляются с этим?
Я бы предпочел не добавлять все эти строки в элементы только потому, что, когда длина файла превышает примерно две строки, сохранение javascript с правильным отступом внутри файла .html.erb - это больше работы, чем нужно
Ответы
Ответ 1
Вот что я делаю (на основе некоторых ответов stackoverflow):
application_helper.rb
def body_page_name
[controller_name.classify.pluralize, action_name.classify].join
end
application.html.haml
%body{data: {page: body_page_name}}
application.js
$(function() {
var page = $("body").data("page");
if("object" === typeof window[page])
window[page].init();
});
И в соответствующем js файле есть объект под названием ControllerAction:
tickets.js
var TicketsShow = new function() {
var self = this;
self.init = function() {
// code which may call other functions in self
};
};
Вероятно, лучший способ сделать это, но это работает для меня
Ответ 2
Я опишу, что я сейчас делаю, на всякий случай, если кто-нибудь даст лучшую идею
1) Я изменил тег body в своем приложении application.html.erb, чтобы добавить текущий контроллер и действие в качестве атрибутов данных
<body data-controller="<%= controller.controller_name %>"
data-action="<%= controller.action_name %>" >
2) Я тестирую это в верхней части соответствующего javascript
$(document).ready(function() {
if($('body').data('controller')=='stories') {
$('.story').click(function(e) {
var u=$(this).data('url');
u && (document.location=u);
});
}
});
Я не могу решить, считаю ли я это хорошей идеей или нет.
Ответ 3
Для JavaScript, специфичного для страницы, я обычно делаю что-то вроде этого:
Помощник по применению
В помощнике приложения я создаю атрибут класса (хотя вы могли бы использовать атрибут данных вместо этого).
module ApplicationHelper
def body_attributes
controller = params[:controller].gsub('/', ' ')
action = params[:action]
version = @version ? "version_#{@version}" : nil
{
class: ([controller, action, version] - [nil]).join(' ')
}
end
end
Примечание. Я также добавляю строку версии. Это помогает в экспериментах с содержанием Google и делает A/B тестирование легким.
Application.html.haml
В моем глобальном файле макета, я делаю что-то вроде этого, чтобы вставить атрибуты в тег body:
!!! 5
%html
%head
...
%body{body_attributes}
script.js
Теперь на моей странице script я просто проверяю атрибуты класса, например:
$(function () {
if ($('body.pledge.new, body.pledge.create').length > 0) {
// do work here...
}
});
Преимущество этого метода заключается в том, что получение тела по классу происходит очень быстро. script внутри условного значения не будет выполняться вообще ни на одной странице, кроме тех, которые я выбираю, поэтому минимальные накладные расходы, и мне не нужно менять свои селекторы по всему коду.
ИЗМЕНИТЬ
Обратите внимание, что этому ответу сейчас 3 года. Вы должны использовать маршрутизацию на стороне клиента с такой структурой, как React.
Ответ 4
Я бы добавил класс в тег BODY, чтобы вы могли идентифицировать каждую страницу и, следовательно, каждый элемент управления на странице.
<body class='page1'>
JS:
$('.page1 button').click(function(e) { $('input.sel').val(this.name); }
Ответ 5
Я сделал это и видел, как это делалось несколькими способами:
-
Установка mvc для загрузки определенного js файла на страницу, названного так же, как файл контроллера. Например: <controller-name>.js
-
Создание парсера url в JS, а затем установка глобальной переменной на текущую страницу: UrlParams.currentView = 'dashboard';
, а затем if(UrlParams.currentView == 'dashboard') { //do specific js here }
-
Установка уникального идентификатора в качестве класса страницы или идентификатора, а затем таргетинга с помощью селекторов JS. $('#dashboard').xyz();