Comments (3)
You can definitely do that. I advocate separating render functions completely into their own files because
- Hot reloading is easier to do
- It makes it more difficult for the view to update model state in unexpected ways (the only sanctioned way is by binding channels to the DOM) There is always the possibility for local state in renderers, what you want is for the model to control access to itself via channels
- Ideologically, model and view should be separate. There are many ways one might want to render a boolean state; so instead of duplicating the state in several components (tickbox component, switch component), separate state and renderer (boolean state + tickbox renderer or switch renderer)
2 and 3 are just my opinion. Raynos does seem to lean more componentwards in some of the examples, for example how most render methods are attached to an object, not completely free.
from mercury.
@shoover is not a requirement of the library just a way in which Raynos do the examples, because he likes more functional programming, in your case I see that you want to use and OO paradigm, a option then is create local state in each component, and attach them to his parent component state, and the state of the parent to the parent-parent state, and soon on till the root State (making you State tree in the process) when the class are loaded, using observ-struct, observ-array, or observ-varhash. if you are careful and understand the code that is really small and easy to comprehend, you will archive the same using the OO paradigm.
this approximation is good for me because In my case when I think about the model of the app, I relate it more with the db data (users, tasks, messages, etc.) very similar to what I should have in my db. the ui for me can represent that data in different ways, so the state of db like data should not be tied to a UI component. and the Ui component should has its own state. (is just my way of thinking)
I archive those things in this way (Warning
: this is pseudo code can contains many errors)
// Create global variable that you will use ref the db models
GLOBAL_VARIABLE = {};
// load your model here, you can define all your model structure like
// you do when use db-schemes using for example an observ-struct (I prefer this way),
// or in scheme-less approximation using observ-varhash
// and reference to the db model in the global variable
GLOBAL_VARIABLE.model = mercury.varhash({});
// load the ui root component, you should create the UI state tree in the process
var ui = new UI()
// Create the app state
var appState = mercury.struct({
"model": GLOBAL_VARIABLE.model,
"ui": ui.state
});
//start mercury
mercury.app(document.body, appState, ui.render);
// Ui class implementation
class UI {
constructor() {
// we create ui root state
let state = {
show: mercury.value("c1");
}
// load your component 1
this.c1 = new Component1();
state["c1"] = c1.state
.
.
.
.
// load your component n
this.cn = new Component_n();
state["cn"] = cn.state
// the magic occurs here
this.state = mercury.struct(state);
// subscribe to child events
this.c1.onClose(this.closeView);
.
.
.
this.cn.onClose(this.closeView);
}
closeView(event, data) {
this.state.show.set("c1");
}
changeView(component = "c1") {
this.state.show.set(component);
}
//=============================================================
// An important note is that the UI.render should has the appState as argument,
// but this is ignored because each component has access to its own state
// and already know where to look for render itself.
//=============================================================
render(state) {
// just ignore the state argument
if (this.state.show() == "c1") {
return c1.render();
}
.
.
.
.
if(this.state.show() == "cn") {
return cn.render();
}
}
// =======================================================
// in case that you want to use the immutable state
// (more mercury way also more safest)
// this will avoid to accidentally or by bad practices change the state
// in the render procedure, if you know what are you doing
// just pick the method that you are comfortable.
// =======================================================
render(state) {
if (state.show == "c1") {
return c1.render(state.c1);
}
.
.
.
.
if(this.state.show == "cn") {
return cn.render(state.cn);
}
}
}
- if you make something like
this.state.form_has_errors = true
(in the c1 component), "the global re-render" will be fired. - For this has effect is important that the child states (or nodes of you observable tree) to be Observ-values, Obsev-Arrays, Observ-Struct, or Observ-Varhash, or some similar object.
- you can access to you db model from the component using the global variable (this model also is a different observable tree).
- also I will recommend you use EventEmmiter or EventEmmiter2 or any similar thing for communication between components ( to communicate events-things-stuff like Modal.onClose), just for avoid read or modify a state outside of its own component (this is more a preference).
- you also can make you own observables structures and use them instead what comes with mercury
- use getter (es6 ) for get your component states instead of directly access to them, also be careful when you want to modify the ui tree observable state (delete or add nodes or a sub-tree), the ideal is that you don't do this type of operation after the mercury app is started. always chose to use resetStates functions instead of deletion, recreation or addition of nodes
tips1: use typescript is of great help in this kind of cases
Sorry for my broken English I hope that this example can help you.
from mercury.
Thank you, @eightyeight and @criloz, for the helpful explanations. I can see there is room for changing designs to suit the application but the examples seem to do it one particular way that ensures a functional perspective. I see this separation enforced in many Elm designs, as well.
from mercury.
Related Issues (20)
- live component reloading HOT 6
- Mercury not exporting virtual-hyperscript SVG HOT 2
- Immutable props
- question: how to detect if a widget has been unmounted HOT 2
- Communication between child components
- Using vdom-to-html doesn't work (returns empty string) HOT 6
- Redux + mercury example? HOT 10
- lock down wiki?
- syntax of h HOT 2
- npm install fails HOT 1
- 14.1.0 break all VNode input rendering HOT 8
- newb question HOT 4
- Docs/Introduction: Simple Cycle example missing
- Synchronize tagged version and comment in mercury.js
- Rendering subitems of different types HOT 4
- What is the right way to pass data to click event handlers? HOT 1
- Get the previous version of state var HOT 3
- Splitting components out to their own render loop? HOT 2
- How to attach state to renderer? HOT 10
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mercury.