As for the "form.length.$error.float", it probably could be a bit more concise, but is it really that bad? What would be a "more semantic" way?
The main strength of angular, is that you are able to point your DOM elements to environment variables in your JavaScript code -- eliminating the need for traversing the DOM to find a mount node. If you are opposed to this functionality and insisting on traversing the DOM from the JS side, I'd love to hear why.
You can find small things you dislike in any framework, but rarely are they valid criticisms of the general concept. Often, these details are there for a reason, and just as often, they are flaws waiting to be fixed by an open source developer.
Angular wants you to learn its vocabulary, and encourages users to expand it further. Like you point out, smart-float is a directive specific to the example. To me, it is a foreign object I don't recognize in html. In fact, directives, scopes?
The big one. Dependency Injection, factories, modules. In JS, this is a solution looking for a problem. There are simpler alternatives to DI. They have issues, but only in theory.
Clarity matters a lot. ng-show="form.length.$error.float". Is there a more simpler way of doing it? There should be; I can't even tell what that means.
I think there are distinctly two camps. I'm in the one which wants frameworks to make me productive with the languages, specs and standards I already know. React (+ router) does this. Backbone does this too, depending on what you're building.
(Edit: replaced semantic with clarity)
Have you taken the time to play around with angular before airing your grievances? My hunch is yes and that you may just be simplifying things for others who haven't used it yet.
For those of you who haven't had the pleasure of working with angular: Once you've familiarized yourself with the verbiage, most of jeswin's concerns here come second nature just by glancing in one's source code. Let's take the example:
form.length.$error.float
The name form, albeit horribly chosen in this case, represents the parent form's identifier in angular (the form's name attribute). It would've made more sense to use <form name="formLengthValidationDemo"> or something more insightful so you could more easily see the name matching from HTML to JS.$error is simply the representation of any form validation errors that may have occurred. It's standard in angular, and there's plenty of documentation. Just google for "angularjs form validation" and you'll find a million resources at your disposal.
form.length.$error.float is checking if an error exists for the validation rule float. Given the limited amount of code in the sample, we'd have to arbitrarily assume that the "smart-float" directive is implicitly setting a custom validation rule via:
ngModel.$setValidity('float')
I'll have to agree to disagree regarding pattern usage and dependency injection. They do have a place, and it tends to be in larger applications which become a burden to maintain as your application grows. To be quite honest, I believe angular brought a simplicity to DI that has yet to be seen in many other frameworks. It entirely lowered the barrier to entry for writing testable code and heavily promoted unit testing at the same time.The declarative style that Angular coaxes you into makes things incredibly easy to understand - you can write code like
<header>
<navbar></navbar>
</header>
<main>
<sidebar></sidebar>
<content></content>
</main>
<footer>
<company-info></company-info>
<credits></credits>
</footer>
And instantly understand what the purpose of these elements are - they're easy to read, they're descriptive, and they're clearly custom elements not part of the normal HTML5 spec, so you can instantly recognize that they must be directives.I can also do simple directives like <loading-spinner></loading-spinner> and create a nice template for CSS to hook into by using the loading-spinner element tag without having to distract from the rest of my DOM with a nesting of 8 divs that can easily be tucked away in a reusable template.
The reason being, considering that HTML5 is an ever evolving spec that it might be possible for a new element to be introduced that could be using the same name as one of your examples. That might muck things up a bit. At least visually, as I would imagine the directives would likely continue working the same as before. It's just that the "they must be directives" logic would fail in that instance.
Interestingly, out of the box Angular provides directives as a, input, or form—meaning that when you write <input> you are, in fact, invoking a directive that provides extra features along with native tag's functionality. While using Angular, you may as well consider every HTML element a directive.
Nevertheless, Angular uses ng- prefix with their built-in directives that don't replicate some existing tag's functionality closely.
<sidebar></sidebar>
can instead be coded as: <span data-sidebar></span>
or something similar.http://w3c.github.io/webcomponents/spec/custom/
The only requirement is that they have a dash in the name. So while <sidebar> is not a valid HTML5 element, <a-sidebar> would be.
Yes, this is actually the recommended practice from the documentation. Built-in Angular directives are typically prefixed with `ng-`, and they suggest that other projects/developers use their own prefixes to avoid conflict.
Why not use XHTML at that point? If XHTML ever had a clear mission statement in life it was that.
I mean I thought XHTML was a curse a few years ago when it was The Thing Every Good Designer Uses™ since it couldn't be rendered as XML in the most popular browser. But hopefully that's not as much an issue anymore. Or maybe it is. I haven't kept up with IE.
Or you know, an adoption of only the needed part, instead of all the BS junk that comes with XML namespaces.
>Why not use XHTML at that point?
Because of all the other junk that comes with it. And because it comes from W3C.
When users gain the ability to define their own tags, you might not know which ones are driven by directives, the custom element, or both even.
Arguments from personal incredulity don't engage substantively with what they ostensibly claim to refute because they import a variable- the argument-maker's conception of what seems plausible- that really should do no work in a logical analysis.
The arguments adumbrated in the parent comment seem to have similar failure modes, adorned as they are with premises such as "to me, [the directive] is a foreign object I don't recognize," and "I can't even tell what that means." Someone who has never programmed before could look at some vanilla javascript and plead perplexity, but obviously this isn't an indictment of javascript itself. To really make the point, the parent comment would have to show that the learning curve is disproportionately arduous for the payoff at the summit, but reiterations of personal unfamiliarity were offered instead.
Jeswin gives no evidence of having made a reasonable attempt to understand Angular ("directives, scopes?"), but more crucially, displays little understanding of the benefits of Angular. DI is criticised as "a solution looking for a problem" in the context of javascript, as if dependency injection were a bandaid for not being a dynamic language. DI enables testability, and not even mentioning this advantage, let alone not providing a cogent argument for why the learning curve of DI doesn't justify the gains in testability, is to refuse to participate in the discussion entirely. Directives are similarly dismissed as "foreign objects," which they might be to some, but they're hugely powerful foreign objects that allow arbitrary behaviour to be written declaratively. Not knowing the benefits of Angular obviously contributes greatly to a reluctance to learn it, and perhaps a subsequent rationalisation of this reluctance as being provoked by something intrinsic to the framework.
Fittingly, after expressing bewilderment regarding Angular scoping, Jeswin goes on to divide the world into two camps, declaring membership in "the one which makes me productive with the languages, specs, and standards I already know", which is about the closest thing to a natural language scoping bug I've come across.
Dependency Injection is a redundant, useless pattern in dynamic languages; especially when it comes to testability.
In test.js:
//paymentService may be an instance or a class
services.paymentService = mockPaymentService;
....
//use paymentService in your tests here.
The above over-simplified example satisfies most test cases. You can convince me with some use-cases.(Edit: You weren't misrepresenting what I said. Removed that claim. I misread, apology.)
Beyond testing, DI makes it much easier to swap in different implementations of a dependency than simply throwing things into the global scope lets you do. Suppose I want to switch my model from one that communicates with Parse to one that communicates with Firebase. Supposing I adhere to the same interface, I should be able to simply drop it in place without affecting other functions or objects that still rely on the Parse version of the model.
Parse and Firebase example:
//someservice.js
...
//works as long as both retain the same interface.
provider = new FirebaseProvider; //new ParseProvider()
//add: just using an if condition, the old fashioned way.
getProvider: function() {
if (config.provider === 'parse')
return ParseProvider()
else
return FirebaseProvider()
Why is writing configuration cleaner than doing the above? That thought process is carried over from projects with lengthy build time.What alternatives do you recommend to DI?
In my test initialization, I'd probably just replace the value of "ns.someService" worldwide with a mock.
Having a window-wide namespace might make sense in the test, but it is pretty risky/limiting if you are writing a component that should be reused in contexts you don't fully control. There are other ways around that besides DI, but they will probably have similar trade-offs in safety EOU, etc.
Here a quick comparison of both: http://versus.com/en/angularjs-vs-react
Here a pretty good video of React's founder pointing on some weakness of Angular: http://www.youtube.com/watch?v=x7cQ3mrcKaY
The cycle probably goes thusly:
Large monolithic framework comes and shows everyone a new way of doing things (Angular/Django).
People think it is too large and monolithic, so make microframeworks (Flask/Whatever comes after Angular).
The next step will be a kind of happy medium.
I predict that the next winner will leverage web components and do the one thing that makes that paradigm better.
(That's why things like rivet and epoxy exist; because backbone doesn't do it right)
"Two way data-binding" is avoided. While it certainly makes for a nifty demo, and works for the most basic CRUD, it doesn't tend to be terribly useful in your real-world app. Sometimes you want to update on every keypress, sometimes on blur, sometimes when the panel is closed, and sometimes when the "save" button is clicked. In almost all cases, simply serializing the form to JSON is faster and easier. All that aside, if your heart is set, go for it.
Or is it simply ppl need to exercise their mental creativity?
JQuery and JS were certainly not dumped, it is just that people writing single page apps moved on and are now using tools that help them.
Well, you can't have Angular without JS so we'll focus on the point of jQuery here.
jQuery does a few things really well – so well that Angular itself uses jQuery (or jqLite by default). angular.element(selector) returns a jQuery object.
Angular also does a few things well. Code reusability and testability are much easier to achieve with Angular, in my opinion. Features like data-binding also help to reduce boilerplate code.
Well you certainly can use it without writing any JS:
https://github.com/angular/angular.dart
However, you're going to compile it to JS when you're done.
As a learning exercise, I wrote a page using just jquery, rewrote it in backbone, and then rewrote it in angular. Backbone helped me separate concerns; Angular helped me do that while writing _way_ less code, since I didn't have to manage keeping the DOM and the JS model in sync.
I redid a relatively trivial CRUD interface from backbone to Angular. The amount of code that I didn't need in Angular was ridiculous. Most of the code in backbone was moving stuff from the DOM into JS. Like var x = $('#elem').val(); kind of things over and over just did not need to be there in Angular.
I think that these kinds of interfaces hit a really good sweet spot with Angular and other databinding frameworks.
jQuery has nothing to do with whether the app is single page or not.
Those frameworks make writing single page apps very easy.
I have suffered trough JEE which is/was really humungous, and Angular is really tiny in comparison.
React is the Holy Grail of JS frameworks.
Here's my article where I analyze this in much more detail: http://blog.reverberate.org/2014/02/react-demystified.html
Also React does not "solve all the problems in the world" -- it says nothing about routing, validation, testability, and many of the other problems that Angular has solutions for.
Passing data to separate components without a shared parent is outside of what React is trying to accomplish but I've handled it before by passing a Backbone model to the separate components as props.
Harder than what?
Also, the "we wouldn't have built many apps" part is a stretch. It's actually the opposite, AngularJS is extremely popular and the most successful current JS framework.
And yes, AngularJS absolutely defines its own language. The directives create an enhanced HTML (that you can enhance even further), and it has its own expression language where you can ask the value of `form.length.$error.float` without fearing null pointers.
This is basically what Angular is about, and why it works as nicely and cleanly as it does. And it's true; learning a new framework is absolutely comparable to learning a new language. Rails is not simply standard Ruby; it defines loads of new stuff that automatically handles things for you below the surface. Spring completely changes the way you work with Java. Grails has its own DSLs for various tasks.
Every framework has a learning curve. And a framework that doesn't change how you think is as useless to learn as a language that doesn't change how you think. But if you don't like learning, you can always simply stick to what you're familiar with.
I agree with your conclusion, but I think you're misusing semantics. This isn't semantic, but neither would anything else be. As soon as we get to using logic, we don't have semantics.
That line is unclear and not easy to understand. That is why I object to it.
'unclear' is a better choice. And less pretentious too, than 'semantic'.
In more recent talks the React devs have avoided using JSX in examples and instead use the compiled form as JSX goes far enough from what people expect that it turns people away before they've given it a chance.
The most important idea to take from React is that UI components are much simpler when they are state machines.
The DOM is what the user sees. That's all. With React, you have a virtual DOM that can hold everything, not just what the user sees. It's a pure data structure, and can be manipulated as such.
Because that DOM is a pure data structure, React can figure out for you what parts have changed, and re-render those bits as needed.
I guess this is why Angular keeps the model separate from the DOM.
That said, the virtual DOM strikes me as a really good idea I'd like to see in Angular.
You won't regret taking a couple of hours to try to build something simple with it.
The weakness with Angular is not the view imo, but the $apply-cycle which can bog down even a modern browser with moderately sized data.
(You can do the same thing with pure JS, there are some forms of simplifying the React.DOM.div() calls, but coffeescript makes it beautiful.)
I could not care less. I find that talk about web programming has been polluted by non-terms like "semantic" that doesn't mean anything specific (in the context).
Especially the whole hoopla with regard to "semantic HTML", with designers (who don't know much if anything about programming, and just heard this "semantic" term from a few industry fad gurus) using it to insist developers should treat HTML as a format for reuse (as if the reason we write HTML is to enable better screen scrapping).
Endless discussions about whether it's ok to a DIV if it's purely for display purposes of not, as if HTML/CSS dont already make a clusterfuck of separating markup from presentation.
Fuck "semantic HTML" -- it's a presentation format, that also happens to have a not-that-functional styling component. If you wan't reuse and semantics, get those from the data level (the db, the REST endpoint, etc), not from code meant for browsers.
Why this is the top comment is beyond me. This is whining.
It is a DOM marker (HTML attribute, element, class or comment) with behavior (JavaScript) tied to it.
Angular lets you create your own HTML attributes. That's what a directive is.
Here is an example from the site:
How semantic is ng-show="form.length.$error.float? smart-float sounds like C++. If programming languages worked like this, we wouldn't have built many apps. The problem is that some frameworks assume that everything should be done with using configuration. What ends up happening is that the configuration (and conventions) becomes its own language. This is a waste of time in the long term; library conventions are not a portable skill set.Some things are just better off with plain JS and simple HTML. FB/Instagram's React is a much better approach to building HTML UIs; you get readable JS and HTML instead of configuration mess.