Проблема с созданием последовательности в Clojure - PullRequest
4 голосов
/ 09 января 2011

[может показаться, что моя проблема с Compojure, но это не так - с Clojure]

Я выдернул свои волосы из-за этого, казалось бы, простого вопроса - но никуда не денусь.

Я играю с Compojure (легкий веб-фреймворк для Clojure), и я просто хотел бы создать веб-страницу, показывающую мой список задач, которые находятся в базе данных PostgreSQL.

Ниже приведены фрагменты кода (пропущено соединение с базой данных, запрос и т. Д., Но эта часть не нужна, поскольку особая проблема заключается в том, что полученный HTML-код ничего не показывает между тегами и ).

В качестве теста я попытался жестко кодировать строку в вызове main-layout, например так: (html (основной макет "Aki's Todos" "Стрижка
Study Clojure
Ответ на вопрос по Stackoverfolw")) - и все работает отлично.

Так что реальная проблема в том, что я не верю, что знаю, как создать строку в Clojure. Не идиоматическим способом, и не вызовом Java StringBuilder также - как я пытался сделать в коде ниже.

Виртуальное пиво и большой голос любому, кто может его решить! Большое спасибо!

=============================================== ==============


;The master template (a very simple POC for now, but can expand on it later)

(defn main-layout
  "This is one of the html layouts for the pages assets - just like a master page"
  [title body]
  (html
    [:html
    [:head
      [:title title]
      (include-js "todos.js")
      (include-css "todos.css")]
    [:body body]]))


(defn show-all-todos 
  "This function will generate the todos HTML table and call the layout function"
  []
  (let [rs (select-all-todos)
       sbHTML (new StringBuilder)]
    (for [rec rs]
      (.append sbHTML (str rec "<br><br>"))) 
    (html (main-layout "Aki's Todos" (.toString sbHTML)))))

=============================================== ==============

Опять же, результатом является веб-страница, но между тегами тела ничего нет. Если я заменю код в цикле for на операторы println и направлю код в repl - забывая о материале веб-страницы (т. Е. Вызове main-layout), набор результатов будет напечатан - НО - проблема заключается в построении вверх по струне.

Еще раз спасибо.

~ Aki

Ответы [ 2 ]

6 голосов
/ 09 января 2011

for ленив, и в вашей функции он никогда не оценивается.Измените for на doseq.

user> (let [rs ["foo" "bar"] 
            sbHTML (new StringBuilder)]
        (for [rec rs]
          (.append sbHTML (str rec "<br><br>")))
        (.toString sbHTML))
""
user> (let [rs ["foo" "bar"] 
            sbHTML (new StringBuilder)]
        (doseq [rec rs]
          (.append sbHTML (str rec "<br><br>")))
        (.toString sbHTML))
"foo<br><br>bar<br><br>"

Вы также можете использовать reduce и interpose или clojure.string/join из clojure.string или, возможно, некоторые другие параметры..

user> (let [rs ["foo" "bar"]]
            (reduce str (interpose "<br><br>" rs)))
"foo<br><br>bar"
user> (require 'clojure.string)
nil
user> (let [rs ["foo" "bar"]]
            (clojure.string/join "<br><br>" rs))
"foo<br><br>bar"
2 голосов
/ 09 января 2011

Вы хотели бы использовать re-gsub следующим образом:

(требуется 'clojure.contrib.str-utils) ;; стоит подумать, чтобы мы могли позже использовать re-gsub

(clojure.contrib.str-utils / re-gsub # "\ newline" "

" ваша строка с разделенными задачами, разделенная с новыми строками)

Эта последняя строка приведет к строке, которая вам нравится. Обязательная часть, как вы, возможно, уже знаете, позволяет компилятору обращаться к мощной библиотеке clojure.contrib.str-utils, не импортируя ее в ваше текущее пространство имен (что может привести к ненужным конфликтам при расширении программы).

относится к reg-exp и позволяет вам определить reg-exp в форме # "regexp", который заменяет все экземпляры, на которые воздействует regexp, аргументом, примененным к третьему аргументу. В этом случае \ newline закрывает способ выражения новых строк в регулярных выражениях, а также строк и символов, которые мы ищем.

Я думаю, что вы действительно хотели сделать, это создать отличный упорядоченный или неупорядоченный список в формате html. Это можно сделать с помощью [hiccup-page-helpers] [2] (если у вас их нет, вероятно, у вас есть compojure за время до его разделения на compojure, hiccup и другие, так как вы используете html-функцию ).

Если вы хотите использовать hiccup-page-helpers, используйте команду re-split из упомянутых выше clojure.contrib.str-utils следующим образом:

(используйте 'hiccup.page-helpers) ;; следите за коллизиями пространства имен, поскольку все функции из hiccup.page-helpers попали в ваше текущее пространство имен.

(неупорядоченный список (clojure.contrib.str-utils / re-split # "\ newline" your-string-with-todos-separa-with-newlines))

который должен сделать аккуратный

  • todo-item1
  • todo-item2

(и да, есть команда упорядоченного списка, которая работает так же!)

В последней строке кода clojure выше все ваши задачи попадают в (список "todo1" "todo2"), который немедленно используется функцией неупорядоченного списка hiccup.page-helpers и там преобразуется в html-ized список.

Удачи в состязании и с друзьями!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...