{"issue":{"state":"open","created_at":"2011-12-09T19:10:18Z","updated_at":"2011-12-10T16:47:43Z","comments":7,"user":{"gravatar_id":"6745667394ecb1c1c5a87f04eeb31e78","id":280456,"url":"https://api.github.com/users/dpx-infinity","avatar_url":"https://secure.gravatar.com/avatar/6745667394ecb1c1c5a87f04eeb31e78?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","login":"dpx-infinity"},"body":"Hello,\r\n\r\nCurrently there is a need to write fairly big amount of boilerplate code if we want to do many things with many components at once (e.g. establish listeners on them, create bindings, lay them out etc). Namely, we have to write something like\r\n\r\n```clojure\r\n(let [component-id-1 (select form [:#component-id-1])\r\n      component-id-2 (select form [:#component-id-2])\r\n      ...]\r\n  ...)\r\n```\r\nwhen we want to use existing components, and something like\r\n\r\n```clojure\r\n(let [component-id-1 (component-1 :id component-id-1 :text \"Text\")\r\n      component-id-2 (component-2 :id component-id-2 :model [1 2 3])\r\n      ...]\r\n  ...)\r\n```\r\n when we want to create new components.\r\nI haven't found facilities to ease this in the library by default so I had to write them myself.\r\n\r\nHere are the macros which target the cases described above.\r\n1.\r\n\r\n```clojure\r\n(defmacro bind-components [form components & body]\r\n  `(let [~@(mapcat #(vector % `(seesaw.core/select ~form [~(keyword (str \\# %))])) components)]\r\n     ~@body))\r\n```\r\n2.\r\n\r\n```clojure\r\n(defmacro with-components [components & body]\r\n  `(let [~@(mapcat #(let [[id form] %\r\n                          [comp & args] form]\r\n                      [id `(~comp :id ~(keyword id) ~@args)]) (partition 2 components))]\r\n     ~@body))\r\n```\r\n\r\n`bind-components` macro targets the first situation, so these forms are equivalent:\r\n\r\n```clojure\r\n(bind-components form\r\n  [comp1 comp2 comp3]\r\n  ...)\r\n\r\n(let [comp1 (select form [:#comp1])\r\n      comp2 (select form [:#comp2])\r\n      comp3 (select form [:#comp3])]\r\n  ...)\r\n```\r\nwhile `with-components` tries to solve second problem, so these forms are equivalent too:\r\n\r\n```clojure\r\n(with-components [comp1 (component-1 :text \"abcd\")\r\n                  comp2 (component-2 :model [1 2 3])]\r\n  ...)\r\n\r\n(let [comp1 (component-1 :id :comp1 :text \"abcd\")\r\n      comp2 (component-2 :id :comp2 :model [1 2 3])]\r\n  ...)\r\n```\r\n\r\nAs you can see, these macros work on assumption that components identifiers are the same as the symbols to which all these components are bound. I think it is the most convenient and obvious way to use seesaw - it greatly reduces the need to remember lots of things at once. These macros go even further - you don't have to type the same identifier twice, first as identifier, second as keyword.\r\n\r\nI'd be very grateful if something like these macros would be added to the library.\r\n\r\nBest regards,\r\nVladimir.","assignee":null,"id":2505440,"labels":[],"pull_request":{"patch_url":null,"html_url":null,"diff_url":null},"number":68,"title":"Convenience macros for bulk components selection/creation","html_url":"https://github.com/daveray/seesaw/issues/68","closed_at":null,"url":"https://api.github.com/repos/daveray/seesaw/issues/68","milestone":null},"action":"created","comment":{"created_at":"2011-12-10T16:47:43Z","updated_at":"2011-12-10T16:47:43Z","user":{"gravatar_id":"6745667394ecb1c1c5a87f04eeb31e78","id":280456,"url":"https://api.github.com/users/dpx-infinity","avatar_url":"https://secure.gravatar.com/avatar/6745667394ecb1c1c5a87f04eeb31e78?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","login":"dpx-infinity"},"body":"Yeah, when I wrote the macro and tried it, it definitely felt better and more consistent than the first one.","id":3091659,"url":"https://api.github.com/repos/daveray/seesaw/issues/comments/3091659"}}