Разное

Underscore js на русском: Underscore.js | русская документация

28.07.2023

Содержание

javascript — Вывести отсортированный список с помощью метода _.sortBy by underscore.js

Вопрос задан

Изменён 6 лет 9 месяцев назад

Просмотрен 391 раз

В проекте использованы backbone + underscore и jade + stylus.

В шаблоне jade имеется переменная, которая выводит не сортированный список

<% _.each(territory_list, function(territory) {%>

Для вывода списка используется метод _.each.

Если я правильно понимаю, чтобы вывести отсортированный список, необходимо использовать метод _.sortBy для выводимого списка territory_list. Но не понимаю где этот метод применить. Представляю что запись должна быть примерно такая (не работает):

<% _. each_.sortBy(territory_list, function(territory) {%>

Как вывести отсортированный список с использованием метода от underscore?

UPD

Уточняю вопрос. В результате сортировки должен вывестись список по возрастающей. Например:

Территория 1
Территория 2
Территория 3
...
Территория 20

и т.д.

  • javascript
  • backbone.js
  • underscore.js
8

Не знаю, откуда взялись ваши представления, но они абсолютно не верны (достаточно мельком просмотреть документацию Underscore.js чтобы в этом убедиться).

Более того, метод _.sortBy нужен не для сортировки массивов строк, а для сортировки коллекций (массивов однотипных объектов). Для сортировки массива строк намного лучше подходит метод

Array.prototype.sort. Но тут есть одна тонкость: этот метод использует лексикографический порядок строк при сортировке. То есть, вы получите:

Foo 1
Foo 10
Foo 2

вместо

Foo 1
Foo 2
Foo 10

Чтобы получить правильный результат, вам нужно использовать натуральную сортировку вместо лексикографической. В общем виде, задача требует отдельного рассмотрения и может потребовать использования сторонних библиотек (например, javascript-natural-sort, но Google расскажет вам и о других, которые могут быть лучше/удобнее).

Если же все действительно так просто, как вы говорите в вопросе (сочетание слова «Территория» и целочисленного ее номера), то вам всего лишь надо передать правильную функцию-компаратор методу Array.prototype.sort:

var territoryComparator = function(a, b) {
    var numRegExp = /(.*?)(\d+)$/;
    return parseInt(a.replace(numRegExp, '$2'))
        - parseInt(b.replace(numRegExp, '$2'))
};

При этом, ваш шаблон должен иметь вид:

<% _.each(territory_list.sort(territoryComparator), function(territory) { %>
    <!-- А здесь вы можете отрисовывать ваши "территории" -->
<% }) %>
0

Зарегистрируйтесь или войдите

Регистрация через Google

Регистрация через Facebook

Регистрация через почту

Отправить без регистрации

Почта

Необходима, но никому не показывается

Отправить без регистрации

Почта

Необходима, но никому не показывается

By clicking “Отправить ответ”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Underscore js

Underscore js

Advertisement

1 of 33

Top clipped slide

Download to read offline

Technology

Underscore.js

Advertisement

Advertisement

Advertisement

Underscore js

  1. Носова О.А. гр.4381
  2.  Что такое Underscore  Имя библиотеки  Общие сведения  Подключение  Функциональность  Underscore в действии  Нужно ли это на самом деле  Аналоги в JavaScript и др. языках
  3. Это библиотека JavaScript, реализующая дополнительную функциональность для работы с массивами, объектами и функциями, изначально отсутствующие в JavaScript, но имеющую аналоги в других языках. Библиотека Underscore сможет облегчить вам процесс разработки, не изменяя встроенных объектов.
  4. Дело все в том, что как в JQuery все начинается со знака «$», так и тут все начинается со знака «_», а Underscore с английского как раз таки и переводится как нижнее подчеркивание.
  5.  На данный момент Underscore предоставляет более 80 функций.  Среди них есть, те, которые решают более тривиальные задачи: map, select, invoke; но так же и более специфические: биндинг, javascript шаблоны и т.д.  Сама библиотека функционально основана на нативных JavaScript методах, таких как forEach, map, reduce, filter, every, indexOf, что делает её значительно быстрой.
  6.  в отличие от Prototype.js, Underscore не модифицирует прототипы встроенных объектов JavaScript. Данная особенность гарантирует бесконфликтность, что позволяет замечательно сочетать этот инструмент с, например, JQuery или Blackbone, или и тем и другим вместе.  Библиотека умеет делегировать вызовы, если какая-то функциональность реализована разработчиками браузеров.
  7. Прежде чем мы начнем использовать эту библиотеку, нам нужно ее подключить. Найти библиотеку вы можете на сайте разработчика underscorejs.org. Заметьте, что там же вы можете найти документацию, однако она будет на английском.
    Если вы хотите прочитать документацию на русском языке, то можете перейти на сайт underscorejs.ru.
  8. Подключить Underscore не сложнее любой другой JavaScript-овой библиотеки. Теперь все доступные методы можем вызывать от объекта “_” (подчёркивание).
  9. Underscore обеспечивает немногим более 80 функций, которые охватывают целый ряд функциональных возможностей. По своей сути, они могут быть разделены на группы :  Коллекции  Массивы  Объекты  Функции  Утилиты  Цепные вызовы
  10.  Коллекцией может быть либо массив или объект, ассоциированный массив в JavaScript, если он семантически правильный.  Underscore предоставляет много методов которые работают на коллекциях.. Вот еще несколько полезных из них:
  11.  Pluck Скажем, у вас есть хороший маленький массив, содержащий пары ключ-значение, и вы хотите извлечь только определенное свойство от каждого.
  12.  map Cоздает массив из коллекции, где каждый элемент может быть тем или иным образом изменен с помощью функции
  13.  All All полезна, если вам нужно проверить каждое значение в коллекции на соответствию критерию.
    Для того, чтобы проверить, пройден ли тест студентом по каждому предмету, например
  14. Underscore имеет кучу функций, которые работают исключительно на массивах, которые в высшей степени приветствуется, поскольку, по сравнению с другими языками, JavaScript предоставляет несколько методов, касающихся массивов
  15.  Uniq Этот метод в основном разбирает массив и удаляет все повторяющиеся элементы, предоставляя вам только уникальные элементы.
  16.  Range Чрезвычайно удобный метод, который позволяет создать ‘диапазон’ или список номеров. Давайте посмотрим на простой пример.
  17.  Intersection Этот метод сравнивает два массива с каждым другим и возвращает список элементов, которые находятся во всех передаваемых массивов, т.е. пересечение в теории множеств. Давайте расширим предыдущий пример, чтобы увидеть, как это работает
  18.  Intersection Легко, не так ли? Вы просто передать в список массивов для сравнения и Underscore делает все остальное
  19. В дополнение к довольно ожидаемым проверкам, Underscore предоставляет различные методы для клонирования, расширения и другие манипулировать объектами.
  20.  Keys and Values Есть массивный объект, где вам нужно только ключи или только значения? Это легко с underscore.
  21.  Defaults Этот метод весьма полезен, когда вам нужно создавать объекты с приемлемыми значениями по умолчанию, когда не могут быть использованы при его создании
  22. Underscore имеет функции, которые работают на функциях. Большинство функций, как правило, довольно сложно объяснить здесь, так что мы посмотрим на самый простой.
  23.  Bind Связывает функцию с объектом. Это значит, что каждый раз когда она будет вызвана this будет указывать на данный объект. Это особенно полезно , когда вы работаете с обработчиком событий , где this переопределен.
  24. Underscore предоставляет массу полезных функций.  Templating Компилирует JavaScript-шаблоны в функции, которые могут быть вызваны для рендеринга этого шаблона. Полезно при рендеринге объёмных и сложных частей HTML-разметки из данных JSON. Полученные функции во время обработки данных могут интерполировать переменные, для чего используется следующий синтаксис внутри шаблона: <%= … %>, а также производить вычисления <% … %>.
  25. Вы можете использовать Underscore с применением как объектно-ориентированного подхода, так и процедурного, в зависимости от ваших привычек и предпочтений. Вызвав chain на объекте, с которым собираетесь работать, вы получите эффект, при котором каждый последующий метод в цепочке будет вызван на объекте, возвращённом предыдущим методом. Чтобы получить результат отработавших методов, нужно вызвать value.
  26. Давайте предположим, что у вас есть случайный набор тестов и вам нужен список тех, у кого 90+ балла. Вы бы обычно пишут что-то вроде этого:
  27. Вы можете подумать, зачем же использовать эту библиотеку, когда есть JQuery? Не стоит их путать. Все дело в том, что в JQuery существует много функций, которые позволяют не беспокоиться, к примеру, с анимациями, а просто вызвать уже готовую. То же самое с Ajax и т.д. Однако эта библиотека не облегчает нам процесс написания кода. Underscore же создана как раз для этого. Давайте рассмотрим некоторые ее возможности на примере.
  28. Давайте посмотрим на то, что мы можем достичь c Underscore в следующем: Код стал короче и более читабельным
  29.  Все зависит от того, что вы пытаетесь сделать. Если использование JavaScript ограничивается игрой вокруг DOM, то ответ почти нет, так как JQuery делает большинство из того, что вы хотите сделать.
  30.  С другой стороны, если вы имеете дело с кодом, не DOM, Underscore оказывается очень полезным.  Underscore предоставляет вам хороший набор абстракций.  Underscore возвращается в исходные реализации, если таковые имеются, чтобы убедиться, что производительность, как оптимальным, насколько это возможно.
  31.  JavaScript – Array,Function,UnderScore,Lo-Dash  Python — itertools, functools,funcy,toolz.fn.py  Ruby – Enumerable, ActiveSupport  PHP – functional-php, Inderscore.php  Clojure – clojure.core  Java – FunctionalJava, lambdaj  C# — LINQ  Objective-C – Underscore.m встроенные внешние

Advertisement

javascript — Как перевести шаблон Underscore в шаблон Handlebars?

Обычно Underscore и Handlebars не являются альтернативой друг другу. Underscore — это набор инструментов с общими функциональными утилитами, которые помогают писать более короткий и удобный для сопровождения код в функциональном стиле. С другой стороны, Handlebars — это библиотека, полностью посвященная рендерингу шаблонов, которая помогает вам писать более чистые и удобные в сопровождении шаблоны.

При использовании Underscore вы можете обнаружить, что его функции вызываются повсюду в вашем коде JavaScript, тогда как Handlebars вызывается только в тех местах, где вы будете отображать шаблон. По этой причине эти библиотеки обычно вообще не конфликтуют; вполне возможно написать приложение, которое зависит от обоих (на самом деле я делал это некоторое время в большинстве своих приложений). Просто свяжите обе библиотеки со своей страницей,

   

или импортировать как модули,

 import _ from 'underscore';
импортировать * как руль из 'рулей';
 

или сделайте то же самое с более старым форматом модуля, таким как AMD или CommonJS.

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

Сравнение языков шаблонов

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

Подчеркивание:

  • <%= выражение %> вставит в текст строковое значение выражения JavaScript . Это называется тегом интерполяции.
  • <%- выражение %> сделает то же самое, но с HTML-экранированием.
  • <% code %> позволяет написать произвольный код JavaScript , который сделает части шаблона условными или повторяющимися. Часто вы обнаружите, что один такой тег выглядит примерно так: <% for (...) { %> , а затем чуть дальше по шаблону есть соответствующий <% } %> . Часть шаблона между этими двумя тегами кода представляет собой цикл, который будет повторяться по логике для 9.0016 . Точно так же вы можете найти <% if (...) { %>...<% } %> , чтобы сделать часть шаблона ... условной. (Честно говоря, это довольно уродливо, но это помогает сделать реализацию минимальной. Модуль шаблона Underscore состоит только из одной страницы.)
  • Внутри кода части <% code %> иногда можно найти print(expression) . Это сокращение предназначено для того, чтобы не выходить из тега кода, вставить тег интерполяции с , выражение , а затем немедленно возобновите работу с новым кодовым тегом. Другими словами, <% code1 print(expression) code2 %> является сокращением для <% code1 %><%= expression %><% code2 %> .

Handlebars:

  • {{имя}} вставляет строковое значение свойства с экранированным HTML-кодом с ключом имя в шаблон.
  • {{{name}}} делает то же самое, но без HTML-экранирования .
  • {{#if condition}}...{{/if}} вставит часть ... , только если условие выполнено.
  • {{#each name}}...{{/each}} будет повторяться ... для каждого элемента или свойства имени . имя становится контекстом из ... ; то есть, если вы напишете {{otherName}} в пределах ... , Handlebars попытается найти otherName как свойство объекта, идентифицированного имя .
  • {{#name}}. ..{{/name}} — это обозначение, которое Handlebars наследует от Mustache. Он ведет себя аналогично {{#each name}} , когда name является массивом, и аналогично {{#if name}} в противном случае (также изменение контекста на name , если это объект). Идея, стоящая за этим (в Mustache), состоит в том, чтобы сделать шаблон еще более декларативным или «свободным от логики», как его называют авторы.
  • Есть еще теги, которые я не буду сейчас рассматривать.

Преобразование шаблонов Underscore в Handlebars

Поскольку Underscore позволяет вставлять в шаблон произвольный код JavaScript, не всегда возможно преобразовать шаблон Underscore в эквивалентный шаблон Handlebars. Однако, к счастью, шаблоны на самом деле не нуждаются во всей выразительной силе JavaScript, поэтому шаблоны Underscore, скорее всего, будут написаны таким образом, что можно портировать на более строгий язык шаблонов («повезло случайно»). Когда это возможно, в большинстве случаев будет достаточно следующей стратегии:

  1. Замените все вхождения print(_.escape(expression)) внутри любого тега <%...%> на %><%- выражение %><% .
  2. Замените любые другие вхождения print(expression) внутри <%...%> на %><%= выражение %><% .
  3. Заменить все вхождения <%-выражение %> (включая те, которые уже были до шага 1) на {{выражение}} .
  4. Замените все вхождения <%= выражение %> (включая те, которые уже были до шага 2) на {{{выражение}}} .
  5. Если вы найдете псевдонимы вида var name = otherName.propertyName где угодно ( кроме в скобках оператора for (...) ), замените otherName.propertyName на name везде, где эта переменная находится в области видимости и отбросить переменную. Не сделать это с переменными цикла внутри for (...) ; они заменяются на шаге 7.
  6. Если вы найдете шаблон вида <% if (condition1) { %>...<% } else if (condition2) { %>...<% } else ... if (conditionN) { %> ...<% } else { %>...<% } %> , начните с последнего, самого внутреннего блока и двигайтесь наружу оттуда следующим образом:
    • Заменить последний <% } else { %> на {{else}} (Handlebars распознает это как специальное обозначение).
    • Замените последний промежуточный элемент <% } else if (conditionN) { %>...<% } %> на {{else}}{{#if conditionN }}...{{/if}}< % } %> . Повторяйте этот шаг до тех пор, пока не останется else if . Обратите внимание, что последний <% } %> остается на месте ; вы вставляете один дополнительный {{/if}} перед ним для каждого промежуточного else if .
    • Заменить самый внешний <% if (condition1) { %>. ..<% } %> на {{#if condition1}}...{{/if}} . На этот раз последний <% } %> исчезает.
  7. Заменить циклы, снова начиная с самых внутренних выражений и продвигаясь оттуда наружу:
    • Заменить функциональных цикла над объектами вида <% _.each(objectName, function(valueName, keyName, collectionName) { %>...<% }) %> нотацией {{#each objectName}}...{{/each}} . Проверить вложенный {{}} / {{{}}} / {{#if}} / {{#each}} тегов в пределах ... для любых вхождений keyName , collectionName или objectName и замените их на @key , .. и .. соответственно (это не опечатка; collectionName и objectName следует заменить на .. потому что они относятся к одному и тому же объекту). Обратите внимание, что функция передана _. each в версии Underscore может принимать меньше аргументов, в этом случае collectionName и даже keyName могут отсутствовать; замена работает одинаково независимо.
    • Заменить функциональных цикла над массивами вида <% _.each(arrayName, function(valueName, indexName, collectionName) { %>...<% }) %> нотацией {{#each arrayName }}...{{/каждый}} . Проверить вложенный {{}} / {{{}}} / {{#if}} / {{#each}} тегов в пределах ... для любых вхождений indexName , collectionName или arrayName и замените их на @index 9001 6, .. и .. соответственно. Опять же, функция, переданная в _.each в версии Underscore, может принимать меньше аргументов; замена работает одинаково независимо.
    • Замена процедурных циклов над объектами вида <% for (var keyName in objectName) { %>. ..<% } %> по нотации {{#each objectName}}...{{/each}} . Проверьте вложенные теги {{}} / {{{}}} / {{#if}} / {{#each}} в пределах ... на предмет появления keyName , objectName[keyName] или objectName и замените их на @key , это и .. соответственно.
    • Замена процедурных циклов по массивам вида <% for (var indexName = 0; indexName < arrayName.length; ++indexName) { %>...<% } %> по нотации {{#each arrayName}}... {{/каждый}} . Проверьте вложенные теги {{}} / {{{}}} / {{#if}} / {{#each}} в пределах ... на предмет появления indexName , arrayName[indexName] или arrayName и замените их на @index , это и . . соответственно.
  8. Исправить синтаксис выражения:
    • Если на предыдущем шаге вы создали выражения вида ...propertyName , где первые две точки .. изначально были именем ( objectName или arrayName , как описано в шаге 7), замените это ../propertyName . У вас могут быть более длинные пути этой формы, например ../../propertyName .
    • Подвыражения вида name[index1][index2] следует преобразовать в name.[index].[index2] (обратите внимание на точки).
  9. Проверьте, все ли выражения и условия , которые вы перевели, могут быть оценены Handlebars как есть. Как правило, Handlebars может напрямую оценивать (вложенные) имена свойств текущего контекста (например, keyName или keyName.subProperty ) и некоторые специальные обозначения, которые он распознает, такие как @key , @index , @root , это и . . . Используйте помощники для оценки выражений, которые представляют собой нечто большее, чем просто имя некоторого объекта, и привязывайте имена по мере необходимости к @root или .. :
    • Обратите внимание, что this.propertyName эквивалентно просто propertyName , потому что this относится к текущему контексту.
    • При передаче в шаблон такого объекта, как {a: foo, b: {c: baz}} , на свойства этого внешнего объекта всегда можно ссылаться с помощью @root.a , @root.b.c и так далее. Обратите внимание, что этому объекту могло быть присвоено собственное имя внутри исходного шаблона Underscore; в этом случае само это имя можно заменить на @root .
    • .. предназначен для ссылки на родительский контекст внутри циклов, как мы видели в шагах 7-8. Иногда цикл в исходном шаблоне Underscore может напрямую ссылаться на свойство родительского контекста, закрывая его; в таких случаях вы можете помочь Handlebars найти нужное свойство, добавив к имени этого свойства префикс 9. 0015 ../ при необходимости.
  10. Возможно, у вас остались пустые <% %> тегов после предыдущих преобразований; их можно безопасно удалить.

Если после вышеперечисленных шагов у вас все еще есть нотация <% code %> в вашем шаблоне или выражения, которые Handlebars не может оценить, вам может потребоваться использовать другие средства языка Handlebars или создать специальные обходные пути. Если вам очень не повезло, то шаблон вообще нельзя будет перевести, но в большинстве случаев способ найдется.

Демонстрация: ваш шаблон

Повторение шаблона подчеркивания из вашего вопроса здесь:

 

<% } else { %> <% } %>> <% если (успех) {%> <% if (rates.length > 1) {%> Для <%- address %> доступны <%- Rates.length %> тарифы на доставку, начиная с <%= Rates[0].price %>. <% } иначе если (rates.length == 1) { %> Для <%-адреса %> доступен один тариф доставки. <% } иначе { %> Мы не отправляем в этот пункт назначения. <% } %> <% } иначе { %> <%- errorFeedback %> <% } %>

<ул> <% for (var i=0; i
  • <%- Rates[i].name %> по <%= Rates[i].price %>
  • <% } %>

    Следуя приведенному выше алгоритму и используя выражение ставок.[1] вместо rate.length > 1 (поскольку Handlebars не может оценивать сравнения из коробки), мы успешно получаем следующий шаблон Handlebars:

     

    {{#если успех}} {{#если ставки.[1]}} Для {{address}} доступны {{rates.length}} тарифы на доставку, начиная с {{{rates.[0].price}}}. {{else}}{{#if ставки}} Для {{address}} доступен один тариф доставки. {{еще}} Мы не отправляем в этот пункт назначения. {{/если если}} {{еще}} {{отзыв об ошибке}} {{/если}}

    <ул> {{#каждая ставка}}
  • {{name}} по цене {{{price}}}
  • {{/каждый}}

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

    Последнее примечание: шаблоны, встроенные в HTML

    Ваша тема включает шаблон на странице со следующим обозначением.

     <тип сценария = "текст/шаблон">
        // шаблон
    
     

    Важно понимать, что хотя это тег