Closed stevekrouse closed 5 years ago
Option 1 and 2 does exactly the same. In the latest version of Turbine option 2 was removed. Essentially all the inbuilt HTML element functions in Turbine accepted an output
property on their input object with the same behavior as using the output
method on components. We removed it to
output
property.As for option 3. Using generator function corresponds to invocations to the chain
method (similarly to how do-notation in Haskell corresponds to invocations of the >>=
operator). We've tried to explain it in the documentation. If that is unclear please let me know. With that in mind I think the question is: what is the difference between the output
method and the chain
method? I think that will take a slightly longer explanation. I will get back to you with that :smile:
Ok, so version 2 is gone and dead. Are 1 and 3 equivalent?
I understand that chain
is bind (>>=
) in Haskell or then
in JS. So how does output
correspond to Haskell?
I guess this relates to my question #93 on go
and fgo
Option 1 and 3 are not equivalent.
Option 3 is very similarly to what Reflex does, it allows for creating views using do-notation (or in our case the go
function) and it supports combining model and view.
Option 1 is unique to Turbine and works well when separating model and view. Option 3 can also be also be used when separating model and view, and we did that in the beginning, but option 1 is ideally suited for this use case. My own opinion is that combining model and view and using option 3 is in most cases a bad idea. But before we can properly have a conversation about that I should explain option 1 properly.
In order to understand the output
method it's important to understand the difference between selected output and available output. This is currently not documented at all, thus I've created the PR #99 to document it. Here's a link to the updated section in the PR that hopefully does an adequate job at explaining it.
The takeway of the added documentation in #99 is this: The output method moves output from the available output into the selected output. When a view is build all the selected output is merged an it becomes the final output.
This makes it very easy to build views with nesting with nested elements. It doesn't matter if a button is heavily nested in some other HTML. It's selected output will "bubble up" as the button is combined with its siblings and parents.
I think the following example would be very annoying to implement using Reflex or option 3 since the a
elements are nested so deep.
const counterModel = fgo(function* ({ incrementClick, decrementClick }) {
const changes = combine(incrementClick.mapTo(1), decrementClick.mapTo(-1));
const count = yield sample(scan((n, m) => n + m, 0, changes));
return { count };
});
const counterView = ({ count }) =>
div([
"Counter ", count,
div([
text("Here is the first button"),
div({class: "button"}, [
a({ class: "btn btn-default" }, "+").output({ incrementClick: "click" }),
]),
]),
div([
text("Here is the second button"),
div({class: "button"}, [
a({ class: "btn btn-default" }, "+").output({ incrementClick: "click" }),
]),
]),
]);
const counter = modelView(counterModel, counterView);
Maybe Reflex has some way of handling this, but as far as I'm aware doing the above is quite boiler plate heavy as one has to write code at every level to get the output to "bubble up". Option 1 in Turbine does this seamlessly.
Let me know if the added documentation in #99 makes it clear how output
works an what it achieves. Otherwise I'll try to explain it more deeply.
Did the explanation above help you @stevekrouse?
This all makes sense. I sometimes have trouble getting Option 3 working correctly, but I guess that's less recommended/supported....
It seems that this issue can be closed now. Option 2 has since been removed in favor of always using option 1 instead. So I guess that improves the situation. Option 3 still works but it's probably more advanced usage and probably not something that a new user would have to even know about.
I'm very confused by the various styles of output:
Are some older styles that still work or are some fully depreciated? It'd probably go a long way towards my sanity if I knew which was the preferred way. (Unless they are not fully equivalent in which case I'd be curious to know the trade-offs of each style.)