(0:00)
Итак, если вы заинтересованы, почему бы нам не сделать небольшой перерыв и не сделать посимпатичнее наш раздел с тегами? Пока что мы в основном брали простейший подход. Но на самом деле, если подумать, его возможностей довольно быстро начинает не хватать. Представьте себе, если у нас есть 20 тегов, то нам придётся использовать довольно большой список для выбора. И некоторые простые моменты, если например у нас выбраны два и мы хотим добавить ещё один, но забыли удержать Cmd... Тогда, конечно же, мы потеряем первоначально выбранные.
(0:30)
И это может немного раздражать.
ОК, давайте отвлечёмся на 5 минут. Мы используем немного JavaScript, чтобы сделать это почище. Мне нравится использовать плагин под названием Select2. Давайте взглянем на несколько примеров. Заметьте, в данном случае это как раз то, что мы хотим. Мы начинаем выбирать, и заметьте, что этот интерфейс для нас гораздо более удобен. И если мне нужно их удалить, я просто нажму на x. Хорошо? Так что давайте добавим его к нашему проекту.
(1:00)
Если я переключусь назад, первый шаг, давайте будем ссылаться на это в CDN... и в конце видео я покажу вам, как загрузить их локально, а затем добавить в ваш gulpfile. Возьмем оба файла и в нашем редакторе мы перейдём на мастер-страницу и разместим это в самом верху. И почему бы нам не взять скрипт, и не вставить его прямо здесь, в нижней части?
Теперь это зависит от jQuery. Так что я стану ссылаться на него ещё раз, пока что непосредственно с их сайта, а затем в конце видео мы всё это скачаем.
(1:30)
Далее мы хотим проверить нашу форму, не так ли? А потом вот здесь мы добавим раздел для подвала. Что нам добавить к подвалу из этого partial? Мы добавим здесь тег скрипта и всё, что мы хотим сделать, это отследить выбор из этого select. Давайте дадим ему идентификатор. Прямо здесь:
'id' => 'tag_list'
Теперь я могу выбрать его с помощью jQuery, а затем вызвать на нём Select2:
<script> $('#tag_list').select2(); </script>
(2:00)
Теперь давайте перейдём в браузер и, похоже, это пытается работать. Но выглядит немного странно. Видимо мы неправильно ссылаемся на наш CSS. Назад на главную страницу. Похоже, мы просто забыли rel=”stylesheet”. Хотя на самом деле мы скопировали и вставили, так что видимо это отсутствовало в документации на GitHub. Я думаю, теперь это исправлено. Да, работает. Круто, это уже выглядит намного лучше.
(2:30)
Только посмотрите на это. Один вызов плагина jQuery, и это работает. Круто. Так что давайте обновим нашу статью, и если мы взглянем, всё работает. Давайте удалим один. Удалим тег coding. Затем обновим статью и всё работает так же, как и раньше, но теперь это явно намного приятнее на глаз и удобнее для ввода.
Отлично.
(3:00)
Я не хочу глубоко копаться в плагине, но покажу вам несколько вещей, которые могли бы быть вам интересны.
Одна из них – временный заполнитель текста. И мы могли бы сказать:
jsplaceholder: 'Выберите тег'
Вернёмся. Обновим, и теперь у нас есть чуть больше обратной связи для пользователя. В нашем случае, обратите внимание, что если мы введём что-то, чего нет в списке тегов, то мы не сможем это выбрать. Я не могу нажать здесь Enter, страница мне не позволяет. А в некоторых ситуациях это именно то, что мы хотим. У нас был этот список тегов.
(3:30)
Вы могли бы отфильтровать его, если вам нужно, но если вы впечатаете что-то, что вам не предложено, значит вам не разрешено это использовать. Так?
Это здорово, но бывают и ситуации, когда, возможно, вы хотите это позволить. Например, у нас есть список тегов, но, возможно, мы хотим дать пользователю простой способ для автоматического создания новых тегов. Так что если я добавлю здесь термин которого не существует, я всё ещё хочу, чтобы его приняли, и затем, за кадром, мы можем определить, что нам нужно создать новый тег.
(4:00)
Таким образом, для пользователя всё будет очень гладко, не так ли? Вместо того чтобы идти куда-нибудь на tags/create, вручную создавать тег, а затем возвращаться сюда и выбирать его.
Так было бы логичнее. Так что, если это подходит для вашего проекта, вы можете установить tags в true:
jstags: true
И на этом всё! Вернёмся, обновим, и на этот раз мы можем выбрать personal или work, но я могу выбрать somethingelse, и обратите внимание, я могу нажать Enter, и мне позволяют это сделать.
(4:30)
Так что просто помните, что если вы пойдёте по этому пути, вы все равно должны за кадром обработать обнаружение случаев, когда вам нужно создать новый тег.
Теперь, пока мы ещё здесь, представьте, что вы на самом деле не хотите передавать теги из контроллера, а может быть, вы хотите получать их динамически. Например вы делаете AJAX-запрос к некоторому URI и он получит некоторую информацию из базы данных и вернёт её. Это могло бы быть полезно. Так что, если это так, то на самом деле, для начала вы можете передать свойство data, и это могло бы быть массивом объектов.
(5:00)
Так, например, id равен one, и текст равен One, и давайте продублируем это просто чтобы дать вам быстрый пример:
jsdata: [ { id: 'one', text: 'One' }, { id: 'two', text: 'Two' }, ]
В данном случае у нас на самом деле уже есть список тегов. Так что эти будут добавлены к тому, что у нас уже есть. Однако, если бы у вас не было этого списка тегов (PHP$tags
), и был только элемент select, то наше свойство data заполнило бы их тегами для выбора. Так что давайте посмотрим. Обновим, и теперь у нас есть здесь One и Two.
(5:30)
Скорее всего вы не захотите жёстко прописывать данные, как я это сделал, и возможно вы захотите сделать запрос в формате JSON. В таком случае вы можете использовать здесь свойство ajax, и потом я просто воспользуюсь функционалом AJAX в jQuery.
Так что я мог бы сказать:
jsajax: { dataType: 'json' }
Мы выбираем JSON из конечной точки в нашем приложении. Краткое примечание, не забывайте, что каждый раз, когда вы возвращаете какой-либо вызов Eloquent непосредственно из метода, типа, PHPreturn User::all();
, Laravel автоматически приведёт это для вас в формат JSON.
(6:00)
Это одна из его интересных функций, так что не забывайте об этом. Но в любом случае мы могли бы установить тип данных, могли бы установить URL для перехода, может быть tags или api/tags:
jsurl: 'api/tags',
Вы могли бы установить задержку, чтобы не работать постоянно, а каждые 250 миллисекунд:
jsdelay: 250
И, конечно, нам нужно передать сюда некоторые данные, чтобы мы знали, какие теги выбирать. Это может быть уместным.
(6:30)
Так что у нас здесь есть наши параметры params, и затем всё, что мы возвращаем, будет рассматриваться в качестве данных запроса. И если мы хотим передать q для запроса или термина, или как там вы захотите его назвать, здесь будет params.term:
jsdata: function(params) { return { q: params.term } }
Так что params.term будет равно всему тому что пользователь наберёт здесь. Понятно? И таким образом, если вы захотите, когда пользователь печатает, вы можете отфильтровывать результаты. И, наконец, это немного не в тему здесь, но если вам нужно обработать результаты, чтобы получить их в нужном формате для использования с плагином, то мы могли бы использовать метод processResults().
(7:00)
Где мы просто укажем как рассматривать результаты. Являются ли они данными или мы выбираем определенное свойство, которое мы возвращаем с нашего сервера:
jsprocessResults: function(data) { return { results: data } }
Это не является действительно необходимым для нашего проекта, но если вы строите что-то с гораздо большим набором результатов, это может стать хорошим способом его отфильтровать. Или, кстати, часто бывает что вы просто хотите выбрать какой-то URL.
(7:30)
Тогда вы могли бы сказать: «Я хочу получить JSON из этой конечной точки». И мы могли бы сказать:
jsurl: 'tags.json'
И теперь плагин Select2 возьмёт файл tags.json, и имейте в виду, что он будет искать его в папке public, поскольку это будет example.com/tags.json.
Так что этот файл должен будет там существовать. Таким образом, он получит эти данные, а затем вам просто нужно обработать результаты, чтобы Select2 знал какой формат он получит.
(8:00)
В данном случае мы принимаем данные, и затем возвращаем всё, что следует рассматривать как результаты от AJAX-запроса:
jsprocessResults: function(data) { return { results: data } }
Да, здесь много крутых штук. Но как я уже говорил, в нашем случае, того что мы здесь имеем нам будет достаточно. Так что вернёмся, обновим и мы можем сделать наш выбор, как делали раньше, но это гораздо лучше, чем то, что у нас было в последнем эпизоде.
Так что теперь, чтобы завершить это видео, идём обратно в app.blade, мы здесь ссылаемся на CDN, что во многих случаях вполне хорошо, однако мы начинаем подходить к месту, где у нас происходит много HTTP-запросов.
(8:30)
И это хороший повод для нас чтобы воспользоваться Gulp и Laravel Elixir. Нашим первым шагом будет получить файлы. Вы можете вручную открыть свой браузер и просто скопировать их в новый файл, но я воспользуюсь wget, который является довольно полезным.
Вы наверняка уже знаете, что это такое.
(9:00)
Если же нет, то если вы знаете, что такое Homebrew, то вы могли бы сделать:
shbrew install wget
или же, если вы понятия не имеете о чем я говорю, то, это нормально, просто вручную получите файлы из браузера. Давайте перейдём в наш каталог resources и почему бы нам не создать здесь каталог css и внутри давайте сделаем ещё одну папку (для наших библиотек):
shcd resources mkdir css cd css mkdir libs cd libs
Хорошо, давайте получим файл (через wget) и готово, мы скачали наш первый.
(9:30)
Далее сделаем то же самое для наших JavaScript-файлов. Выйдем из этой папки и создадим новую для файлов JavaScript. И давайте сделаем то же самое для каталога libs:
sh../ ../ mkdir js cd js mkdir libs cd libs
ОК, на этот раз мы получим jQuery:
shwget http://code.jquery.com/jquery.js
Круто. И далее мы также хотим получить плагин Select2.
Прекрасно. Теперь у нас есть всё, что нужно, мы можем перейти к нашему gulpfile и почистить его.
(10:00)
Почему бы нам не начать с CSS? Мы подтягиваем Bootstrap, затем наш файл app, и затем Select2.
Хорошо, давайте вернёмся к нашему gulpfile.js.
Мы смешиваем Sass, и далее некоторые таблицы стилей. По умолчанию для метода styles() базовым каталогом будет resources/css, но, конечно, вы можете его изменить. Далее, похоже мы хотим libs/bootstraps.min.css, и затем app.css, которого пока ещё там не существует:
jsmix.styles([ 'libs/bootstraps.min.css', 'app.css' ])
Сейчас мы компилируем всё в папку public, так что нам стоит поменять этот путь. И я покажу вам место где его поменять, и обратите внимание, тут мы передаём исходные файлы, а затем вторым параметром будет выходной путь. Давайте установим его в resources/css. И кстати, позвольте я вам покажу, как это выглядит.
Если мы запустим: shgulp
.
Теперь вы увидите что файл app.css сохраняется здесь (в resources/css). Круто.
(11:00)
Так что теперь, когда мы смешиваем наши стили, мы берём bootstrap, app, и затем, если вы помните нам нужен select2.css. Так что это наш окончательный файл:
js'libs/select2.min.css'
ОК, это хорошо выглядит. Давайте удалим наш каталог public/css, чтобы вы могли увидеть, что мы здесь получим с нуля. Мы запускаем Gulp, и теперь, если мы посмотрим здесь (в public/css), всё готово. Этот CSS-файл включает в себя содержимое всех трёх файлов.
(11:30)
Не забывайте, просто чтобы освежить вашу память, когда вы будете готовы для производства сделайте:
shgulp --production
и готово, именно то, что вы хотите.
И это значит, обратно в app.blade, посмотрите, мы можем удалить это всё и заменить вот так:
<link rel=”stylesheet” href=”/css/all.css”>
Теперь мы просто должны сделать то же самое для наших скриптов. И на этот раз мы хотим jQuery и затем плагин Select2. Итак, вернёмся к gulpfile, мы смиксуем на этот раз несколько скриптов, и как и для стилей, базовым каталогом для них будет resources/js.
jsmix.scripts([ 'libs/jquery.js', 'libs/select2.min.js' ]);
Теперь, если мы запустим это (shgulp
) мы получим файл public/js/all.js. Вот и всё что нам нужно.
Кстати быстрое примечание в тему, если вам не нравится название all, то вы можете назвать файл как хотите. Например, вы можете сказать:
js], 'public/js/output.js');
или на самом деле всё что угодно.
(12:30)
Так что, если это то, что вы хотите, то можете сделать так.
ОК, давайте мы всё-таки будем использовать значение по умолчанию. Теперь вернёмся к нашей главной странице. Ещё раз мы можем удалить здесь всё целиком и заменить на /js/all.js. И теперь мы не только очистили нашу мастер-страницу, но мы также улучшили производительность, так как больше у нас нет этих различных HTTP-запросов.
(13:00)
И, конечно же, если вам нужно доказательство того, что это всё ещё работает, я уверяю вас, что всё в порядке. Так круто. В этом эпизоде мы не только узнали как упростить процесс добавления и удаления тегов, но мы также использовали Gulp и Laravel Elixir для повышения производительности. Так что давайте на этом и остановимся.