This is actually a feature of React: your UI is guaranteed to always be in sync with your underlying data!
...
It sounds like you want to be able to show either an exact °C temperature or an exact °F temperature, so the best approach here seems to be to store that as well. Otherwise, you're feigning more precision than you actually have.
The way I thought about it is that a temperature conversion model entity needs 4 API points (get as °C, get as °F, set as °C, set as °F), and you want the canonical precision to be bound to the latest modified unit of temperature.
The "mathematically correct" approach would get pretty complicated with a fraction library and value objects, but given that the output of the conversion cannot always be expressed as a decimal on the UI in the first place, and that the weight of the "correct" solution far outweights adding a second storage variable, we can make an engineering decision to simplify the implementation while staying correct enough for the purposes of the example. In fact, the vanilla JS implicitly does the exact same thing by storing the canonical precision in the last modified field's `value` attribute.
Typically, you'd want to store the result of a computation when setting anyways, since re-computing them on every read can be expensive.
In code, this simply means that you store the latest modified value as-is, and store the imprecise computed value for the other unit of temperature:
var Temperature = function() {
this.setCelsius = function(c) {
this.celsius = c
this.fahrenheit = 9/5 * c + 32
}
this.setFahrenheit = function(f) {
this.fahrenheit = f
this.celsius = 5/9 * (f - 32)
}
}
var t = new Temperature
t.setFahrenheit(2) //we want 2°F to mean 2°F, not 1.999...
As a related note, it's kinda curious that some of the implementations end up having slightly different semantics, specifically in order to fit into their frameworks (and an implicit desire for terseness), and sacrifice code quality (in terms of logic encapsulation, computational cost profile, etc.) to achieve that end.
The issue I have with this is that these apps are not all doing the same thing.
You are not required to use models in Backbone, especially for such a trivial example. You aren't using an equivalent of models in the vanilla JS example. You aren't required to listen to change events to render anything.
Here is a simple Backbone view doing an equivalent to what the vanilla JS example is doing:
This is the fundamental flaw in comparisons like this that take frameworks designed for huge projects and demonstrate them with a mini-project.
Of course the Backbone example looks over the top. And compared to all of them the vanilla JS looks like an example of beautiful simplicity. But try making a full webapp using vanilla JS and you'll find things get very messy, very fast.
Never mind the fact that the entire point of frameworks like React is that they're performant with a lot of DOM changes being made frequently. Making a demo that shows it altering one text box isn't really very useful.
I disagree. You can write robust, clean, modular, and scalable code without a framework. If you need a framework to help you "stay within the lines" or speed up development, then by all means. But I've built large JS systems with vanilla js + jquery + requirejs just fine.
Any non-trivially sized software system will use a framework to avoid code duplication. You can either choose someone else's framework, or roll your own, but unless you're a framework design wizard you're unlikely to build an all-purpose web dev framework which beats the well known ones.
Which is to say that I definitely recommend that everyone at some point develop their own all-purpose framework, because it's a great learning experience, but if they're doing production work they should stick to one of the existing ones, even if it's just so other developers will have an easier time understanding the codebase.
How do you explain the mountains of code written before the great frameworks saved us all? Is it all bad? Is it all an ad-hoc framework? On all of the framework-less projects I've worked on, what emerged was significantly better than a framework: it was a real domain model that was decoupled from all of the irrelevant technical details.
I know, nobody does that cause it's hard. The frameworks certainly don't help.
You can write great software without MVC, or frameworks, or OOP. Frameworks are often crutches for people's anemic design skills. They're not nearly as important as everyone thinks. You can easily coordinate multiple people working by, you know, sketching out an architecture amenable to he division of labor.
Yes, it is all an ad-hoc framework. There are no large frameworkless projects. Programming languages don't come with enough abstraction to model a large domain (unless you're using a 4gl, but those are semi-frameworks). You always end up building or reusing additional abstractions, and those collectively are a framework. The framework can be procedural, functional, declarative, oop, mvc, or any of dozens of additional buzzwords, but you cannot avoid having one.
Anyway, my point is that if you're working on a non-trivial solution in a problem domain that other people with good design skills have built frameworks for (like web dev, the most oversolved domain in software, aside from text editing), it doesn't make economic sense to roll your own. Even if you have the rare trait of good design, the productivity benefit for yourself by having a more closely adapted framework is washed away by the cost of building it and having to bring other people up to speed on it. I've had the experience of lots of home-grown framework code, and rolled my own quite a few times, and the longer i've had to observe other developers working on that code the more convinced i've become of NIH being a programming anti-pattern. It can make sense to roll your own, but for the majority of web dev programming it doesn't. There may be categories of software dev where the statement inverts though, i'm not going to generalize too far.
What i however also think is that many of today's frameworks are overengineered and force you to write too much code to solve a problem. They suffer from tdd-induced design damage, as dhh would describe it (the recent discussion between fowler, beck and dhh was enlightening). Many frameworks have optimized for secondary goals like orthogonality or compliance to design patterns instead of primary goals like fitness for purpose, speed of development, maintainability, and usability of the resulting product. However, i'm of the opinion that even given all that, for general web dev and for most people, it's better to use one of the common ones than to roll their own. They'll build a more maintainable solution in less time.
Are you familiar with the idea of the Turing Tarpit?
We have a similar thing here: The issue isn't whether you can do X with/without framework Y. It's whether framework X is more cost effective vs. framework Z (or no framework): Does it require less/more boilerplate? Is it less/more error-prone? Does it mean that more/less experience is needed to do the right thing? Does it mean that testing becomes harder/easier? &c.
Easier for a single person to do. But with decent sized group you're going to find yourself having to establish all sorts of patterns anyway... which are exactly the patterns a framework provides.
Check out the Mithril example in the comments (http://jsfiddle.net/qQ59s/). I'm finding Mithril to be the most straight-forward, easiest to understand framework I've used. Note that Mithril does DOM diff'ing.
IMHO, Vue is a very interesting project and I think this particular article is a very good fit to show its strengths, but I think my comment (at the bottom of the article) still applies to it. For example, it's not particularly obvious how to change a binding to use the blur or the change event, without scouring the documentation. Or that `v-model` and `computed` and `$get` and `$set` are the names of the things that, in conjunction, do what you want in this particular case.
In that sense, the Mithril code is more straightforward to write and to control, because the abstractions that it provides complement - rather than replace - a naive implementer's workflow. This is the aspect that I believe eddyystop is talking about.
This is the first I have heard of Vue and am impressed by its simplicity and intuitiveness.
In particular, I like that the JS code is free from cruft as in the other examples there. I also like that the HTML stands on its own which makes the UI design process easier.
But what I have emphasised on is that vanilla JS, with zero dependencies, is actually shorter code than any other solution. And works just as well. Not that you'd want to develop all applications without the help from libs/frameworks, but sometimes that abstraction simply adds unnecessary complexity.
Well, of course frameworks add more boilerplate when you compare small problems. You get the benefits of a framework only after your application scales.
I found that I had absolutely no need for jQuery, etc. Just do all UI stuff with CSS+HTML and use Knockout's data binding for binding it to data and logic.
Knockout is a little rough and has some weird edge-case gotchas and syntactic inconsistencies but I like it. Might look at Mithril in the future.
Still no JS UI framework nirvana as near as I can see.
I've found Mithril to suit my way of building JS single page apps perfectly, I highly suggest having a play with it. It feels very different to begin with, but once you've grokked it, you can fit the whole "framework" (it's more of a library + conventions) in your head! Thats its most powerful feature for me -- along with the syntax-errors-in-my-templates and the component/module system.
This comparison of two-way data bindings assumes that, well, two-way data binding is the way to go. Without taking a stance on whether this is wrong or not, the usage of React here is a bit misleading. React puts emphasis on unidirectional data flow. It's a different model completely. The two-way binding _helper_ happened to be there as sugar only. In fact, here's the note on the add-on page (http://facebook.github.io/react/docs/two-way-binding-helpers...):
If you're new to the framework, note that `ReactLink` is not needed for most applications and should be used cautiously.
I was web JS dev for a long time, didn't really touch any other platforms for 2 years (except for small scripts and automation, nothing big).
Then I started doing CocoaTouch for a project with a friend. I can't view the source, and the tools suck ass (xcode, obj-c) but compared to Javascript and especially the frameworks for web apps, it's wonderful!
The JS frameworks, all of them, make things a hundred times more complicated than they need to be. If web programming was like CocoaTouch, but with a dynamic language, it would be great. /rant
But the complexity that emerges is not from supporting multiple devices! It comes from retrofitting everything atop a model originally designed for navigating a graph of linked documents. This is a severe deficiency in the original design, and no framework can patch it over. As developers, we're the ones left holding the pieces to an abortion of design day after day. This state of affairs is unacceptable.
I remember when Swing was big. Everyone was gushing about it despite obvious flaws: non-native UI, poor startup time, horrible accessibility, and ridiculous memory consumption. Industry loves the idea of one platform-to-rule-them-all, no matter how far behind the uber-platform is. It would rather dump endless amounts of money and time into a patchwork of hacks than admit that it was wrong.
We're way past due for a VM for webapps. I don't see why the VM couldn't be added as a dual to the current HTML/JS/CSS model. URIs beginning with app:// would use the new VM model. There's a shocking amount of defeatism, both by developers and institutions surrounding the tooling of webapps.
We've had VMs for webapps, more or less: Java Applets, Flash, Silverlight. They've all been deficient too, and Javascript on top of the DOM with HTML/CSS has won out. I don't think changing the url protocol would make a difference (and people will still want to embed apps in html pages, and interoperate with JS on those pages.)
I don't know what the answer is, and I agree with you that a huge part of the problem is that trying to build web applications on a platform intended for web documents doesn't work very well. But it seems to work better than everything else we've tried.
This is pretty much every UI system I've worked with contrasted against HTML/JS/CSS.
I'll be the first to say: creating views in those systems is usually not as easy as HTML. But the coherence of the tooling makes up for it quickly.
It appears the development ecosystem is optimizing itself around what lets you throw shit up as fast as possible, regardless of how coherent or painful it is to modify in the future. Time-to-market has always been a concern, but the notion of Internet-time has only accelerated things.
This also explains why R&D has taken a backseat many times; we often confuse it with new products (that use the same tech).
But when you use CocoaTouch you can only deploy to Apple devices. When there's only one platform to target it's hardly surprising that it's easier to work with.
Java/Python are (arguably) easier for writing complex standalone apps, and neither of those are platform agnostic. The problem isn't that JS is cross platform and other languages aren't.
God, I've not known of the oninput event. I've always used onkeyup, or onchange instead. And their behaviors were so tricky. These "vanilla JS" features sometimes surprise me. Shame on me.
This is actually a feature of React: your UI is guaranteed to always be in sync with your underlying data!
...
It sounds like you want to be able to show either an exact °C temperature or an exact °F temperature, so the best approach here seems to be to store that as well. Otherwise, you're feigning more precision than you actually have.