Re: om: state management considerations
Hi, Thank you for all answers, as I did my homework (reading overview sent by Jeff and applying Luca's suggestions), things have improved quite a bit. Yet there are still some things I'm not fully grasping, so I have more questions :) First one is about object created by (om/build ...) - in all tutorials these objects are always created on the fly in (render ...) functions. So if some component disappears from view for some time, it loses its state. This might be the case in tab panels for example: views representing individual tabs disappear when user switches onto another tab. Is it safe to retain reference to such view created by om/build or should it be build from scratch every time ? Second thing is inter-component communication. I assume that meddling with state of one component from another component (eg. reading data from edited row by data grid) is considered harmful and core.async channel should be used in such cases which implies actor model for UI app. Is it safe to assume that om is opinionated in this regard (using actor model for communication) ? If so, are there materials regarding proper design and structuring of actors and their communication (think: GoF-like 'design patterns' for actor model) ? I've read some parts of a few Erlang books regarding some of it but it seems to cover only basics and simple cases. Thenk you and Regards, rle -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: om: state management considerations
On Wed, Apr 2, 2014 at 3:42 AM, rlewczuk rafal.lewc...@gmail.com wrote: First one is about object created by (om/build ...) - in all tutorials these objects are always created on the fly in (render ...) functions. So if some component disappears from view for some time, it loses its state. This might be the case in tab panels for example: views representing individual tabs disappear when user switches onto another tab. Is it safe to retain reference to such view created by om/build or should it be build from scratch every time ? In the case of tabs I would generally not destroy the view but simply hide it with styling. Views should always be built from scratch every time - it is not expensive :) Virtual DOM FTW. Second thing is inter-component communication. I assume that meddling with state of one component from another component (eg. reading data from edited row by data grid) is considered harmful and core.async channel should be used in such cases which implies actor model for UI app. Is it safe to assume that om is opinionated in this regard (using actor model for communication) ? If so, are there materials regarding proper design and structuring of actors and their communication (think: GoF-like 'design patterns' for actor model) ? I've read some parts of a few Erlang books regarding some of it but it seems to cover only basics and simple cases. Yes for coordination between components I would use either callbacks in the simple case and channels in the complex one. David -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: om: state management considerations
Hi Rle, I'm a clojurescript / om newbie too. I'll try to answer to the best of my knowledge and maybe someone else can improve this first guess. Il giorno giovedì 27 marzo 2014 09:20:41 UTC+1, rlewczuk ha scritto: Hi, After playing a bit with om, I'm somewhat confused about state maintaining possibilities it offers. There is global application state and local component state. I have some doubts about using local state as it seems to lead to troubles as soon as code grows a bit (I'm thinking about traditional widgets, eg. data table with editing capability - somewhat boring stuff, yet quite common in many cases). Most common approach to this seems to be to set up some local state and then use core.async channels for communication and updating global state asynchronousluy (go ...) blocks. My feeling is that it creates lots of places with application state which negates to some extent main premise of state handling by om. Do I need to use local state at all ? Are there any alternatives ? I'm thinking about using keyword namespacing in global state to separate concerns, for example viewed data table row could be kept as something like :d/current-row somewhere in global state ('d' stands for data) but when row editing starts :e/current-row appears and is used by input fields ('e' stands for editing). UI configuration (column descriptions etc.) would use 'u' prefix (eg. :u/columns) for example etc. Don't mess up application state with view state information. You can keep your current / editing row in the local state of a table component that contains your row components. As a further optimization you may render your table as pure html and mount a row component over one row only when editing it. Om components are already flyweight. If it's feasible and how easily it can be done seems to be a matter of react.js (owner of mount / unmount lifecycle) more than om. As a rule of thumb for myself: application state should not change if you change your view (e.g. represent data with a table or with a chart). It may be bound to your use case. So if it contains some flags for user interaction they are ok. My feeling is that keeping application state strictly in global state would make some things easier (testing+debugging UI components, recording user sessions in full detail by listening on :tx-listen etc.). But blindly following all-in-global state also can have its pitfalls that I'm not aware of (as cljs/reactjs/om newbie). When you add a component you need to make rooms for its state in the application state. I fear this is very error prone. There are the following aspects of UI state as I see it: - hardcoded UI config data (widget descriptions, column descriptions etc.); pass them in as :opts - customizable UI config data (eg. skins and styles that application user can choose); in the application state; you can load / store them in a user profile at the server side - UI code (function references sometimes bound somewhere to application state); (not sure I understand the question) may be in functions in the same file of your component definition functions - UI state (eg. currently edited data, flags marking that data is being edited/viewed row being selected etc.) in local state - business data (fetched REST from backend); in application state - inherently stateful stuff (eg. core.async channels); in local state or in global shared state for inter components communication - etc. My question is: where would you recommend placing individual bits of config/data/state listed above (global state? local state? :opts ? global :shared ? etc.) ? Regards, rle I hope this helps, Luca -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
om: state management considerations
Hi, After playing a bit with om, I'm somewhat confused about state maintaining possibilities it offers. There is global application state and local component state. I have some doubts about using local state as it seems to lead to troubles as soon as code grows a bit (I'm thinking about traditional widgets, eg. data table with editing capability - somewhat boring stuff, yet quite common in many cases). Most common approach to this seems to be to set up some local state and then use core.async channels for communication and updating global state asynchronousluy (go ...) blocks. My feeling is that it creates lots of places with application state which negates to some extent main premise of state handling by om. Do I need to use local state at all ? Are there any alternatives ? I'm thinking about using keyword namespacing in global state to separate concerns, for example viewed data table row could be kept as something like :d/current-row somewhere in global state ('d' stands for data) but when row editing starts :e/current-row appears and is used by input fields ('e' stands for editing). UI configuration (column descriptions etc.) would use 'u' prefix (eg. :u/columns) for example etc. My feeling is that keeping application state strictly in global state would make some things easier (testing+debugging UI components, recording user sessions in full detail by listening on :tx-listen etc.). But blindly following all-in-global state also can have its pitfalls that I'm not aware of (as cljs/reactjs/om newbie). There are the following aspects of UI state as I see it: - hardcoded UI config data (widget descriptions, column descriptions etc.); - customizable UI config data (eg. skins and styles that application user can choose); - UI code (function references sometimes bound somewhere to application state); - UI state (eg. currently edited data, flags marking that data is being edited/viewed row being selected etc.) - business data (fetched REST from backend); - inherently stateful stuff (eg. core.async channels); - etc. My question is: where would you recommend placing individual bits of config/data/state listed above (global state? local state? :opts ? global :shared ? etc.) ? Regards, rle -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: om: state management considerations
There is some explanation about component local state in the documentation here: https://github.com/swannodette/om/wiki/Conceptual-overview UI components will often have transient state that really doesn't make sense to expose externally. For example the characters in an input as someone is typing, or the highlighted? bool for some mouse-over logic, that kind of thing. Also, component local state is always up to date, whereas the global state is updated in a more stepwise fashion with each call of the render loop. -Jeff On Thursday, March 27, 2014 4:20:41 PM UTC+8, rlewczuk wrote: Hi, After playing a bit with om, I'm somewhat confused about state maintaining possibilities it offers. There is global application state and local component state. I have some doubts about using local state as it seems to lead to troubles as soon as code grows a bit (I'm thinking about traditional widgets, eg. data table with editing capability - somewhat boring stuff, yet quite common in many cases). Most common approach to this seems to be to set up some local state and then use core.async channels for communication and updating global state asynchronousluy (go ...) blocks. My feeling is that it creates lots of places with application state which negates to some extent main premise of state handling by om. Do I need to use local state at all ? Are there any alternatives ? I'm thinking about using keyword namespacing in global state to separate concerns, for example viewed data table row could be kept as something like :d/current-row somewhere in global state ('d' stands for data) but when row editing starts :e/current-row appears and is used by input fields ('e' stands for editing). UI configuration (column descriptions etc.) would use 'u' prefix (eg. :u/columns) for example etc. My feeling is that keeping application state strictly in global state would make some things easier (testing+debugging UI components, recording user sessions in full detail by listening on :tx-listen etc.). But blindly following all-in-global state also can have its pitfalls that I'm not aware of (as cljs/reactjs/om newbie). There are the following aspects of UI state as I see it: - hardcoded UI config data (widget descriptions, column descriptions etc.); - customizable UI config data (eg. skins and styles that application user can choose); - UI code (function references sometimes bound somewhere to application state); - UI state (eg. currently edited data, flags marking that data is being edited/viewed row being selected etc.) - business data (fetched REST from backend); - inherently stateful stuff (eg. core.async channels); - etc. My question is: where would you recommend placing individual bits of config/data/state listed above (global state? local state? :opts ? global :shared ? etc.) ? Regards, rle -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.