Re: om: state management considerations

2014-04-02 Thread rlewczuk
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

2014-04-02 Thread David Nolen
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

2014-03-31 Thread icamts
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

2014-03-27 Thread rlewczuk
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

2014-03-27 Thread Jeff Rose
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.