
Classy: Cleaner class-based controllers for AngularJS - LX-350
http://davej.github.io/angular-classy/
======
SchizoDuckie
There is really no need for this. It adds _nothing_ imo but another layer of
sauce over what angular already does properly.

If your controllers are getting huge, go refactor into directives and
services. I don't see how this would help since there isn't even inheritance?

also:

    
    
        app.controller('AppCtrl', ['$scope', '$location', '$http'], function($scope, $location, $http) {
        // ... 
        }]);
    

vs

    
    
        app.classy.controller({ name: 'AppCtrl', inject: ['$scope', '$location', '$http'],
          //...
        });
    

Congratulations, you have saved absolutely nothing (10 bytes? ) and just made
it harder for me to understand your angular app.

One of the brilliant things about angular is that it provides a proper
structure that anyone that needs to write angular needs to adhere to. If you
start introducing layers upon layers of funkyness and glitter, you'll end up
with something non-angular.

what I mean by that is: Classy introduces new conventions in a frameworks that
already has a _lot_ of conventions to keep track of while coding, and my
biggest argument against this is that you introduce a dependency to Classy for
all code based upon it, therefore you've created an extra layer of complexity
to fix and track down when angular changes.

In my mind effort like this should go into the angular core to make it better.

~~~
davej
Thanks for the feedback. I would argue that the Classy example is more
expressive and crucially it is DRY.

Edit:

> One of the brilliant things about angular is that it provides a proper
> structure that anyone that needs to write angular needs to adhere to

Angular doesn't provide structure for controllers, they are just javascript
functions. If you want to add structure it is up to the individual developer
to decide how to do it. Classy is just the way that I like to do it, Classy is
opinionated so it won't be for everyone.

By the way, you can do inheritance but I haven't documented and fully tested
it yet.

~~~
SchizoDuckie
Angular's dependency injection is still a matter of discussion and a lot of
people are not completely happen with it. It'll also be made into something
different for angular 2.0.

Still, besides that: DRY is IMO not about these 2 lines that you've refactored
away here. It's about whole functions/classes that have similar functionality
where you're repeating yourself.

Therefore, this would be a micro-optimisation with negative results on impact
on performance most likely (since there's more overhead)

~~~
sanderjd
The point of DRY is to reduce the types of errors that repetition lends itself
to. A very common member of that class of errors is "I should have repeated
something, but I didn't". It is pretty easy to run into that error with
Angular's injection - you can forget to add either the string or the argument,
or (worse) you can get the order wrong. Eliminating the repetition fixes that
class of errors, so I think it's well within the realm of "what DRY is about".

~~~
bilalq
I can see Classy adding value, but repetition with dependency injection is a
solved problem if you use ngmin[1].

[1]: [https://github.com/btford/ngmin](https://github.com/btford/ngmin)

~~~
sanderjd
I disagree that ngmin is a full _solution_ to the problem. It is a good and
very helpful tool, but it's a hack and a pretty leaky one - I think it's often
less of a hassle to just write all the explicit injection syntax myself than
to fiddle with formatting to get ngmin to work and track down issues when it
doesn't. Classy's solution seems much nicer to me.

~~~
Cthulhu_
I have no idea what you're talking about; I've never had any issues with ngmin
or angular's default (i.e. non-array / string) injection methods.

~~~
sanderjd
I guess your mileage may vary, but in my experience, it isn't difficult to
write reasonable code that ngmin fails to handle properly, and it's difficult
to debug when it happens. It seems the best thing to do is to start with ngmin
from the get-go and adopt a style guide that works with it. But I like the
idea of a library that abstracts it away altogether.

------
chm
This is actually great for someone learning Angular. It's just a different way
of presenting the exact same material. I was completely dumbfounded at first
when learning Angular. This would have helped.

I very much suggest everyone interested in Angular development to read what
the guys at MeanJS.org[1] have to say about structuring modules. It helps me
think about my app a lot better. The structure could be cleaned up a bit
though (e.g. module A can use module B's filters at run-time, this is a bad
thing IMO. There should be global and local filters).

[1]:[http://meanjs.org/docs.html#angularjs-
modules](http://meanjs.org/docs.html#angularjs-modules)

~~~
jradd
I just want to let you know that I really appreciate your empathetic
suggestions for those [like me] trying to learn intermediary aspects of
AngularJS; of which I am going to relate to—the learning of how to walk——and
then applying that knowledge to break atmo and venture into the stars. :)

TLDR; THANK YOU (Intermediary AngularJS learning–curve is friggin hard.)

~~~
chm
You're welcome. I am an AngularJS neophyte as well... but the mental picture I
have of the framework is definitely clearer than it was two months ago!

------
davej
Oh wow, this is my little project, cool to see it on the front page of Hacker
News. :-)

~~~
jonny_eh
It's a really nice demo page. What do you use for the code highlighting?

~~~
davej
Thank you. It's just CSS and the :hover pseudo-selector, the popover effect is
done using CSS keyframe animations.

Fun geek fact: The Mac OS style close/minimize/expand buttons on the code
editor are written in CSS, they're not images. A bit of a pointless exercise
but a fun little easter egg.

------
tdicola
Interesting project--I've done a little bit of Angular development and would
be curious to look at this the next time I come back to Angular.

As a side note, I am always impressed and insanely jealous of the nice
websites that frontend libraries make for themselves. It makes sense since
obviously folks with more frontend experience are writing the libraries, but I
wish there were nice templates or tools to make such nice and informative
pages. Would be cool to see stuff like python, boost, etc. with clean,
responsive, easy to read web pages.

~~~
MozMorris
In relation to your side note, perhaps a site like
[http://html5up.net/](http://html5up.net/) might be of use. I'd be interested
if others have other similar resources they use.

~~~
pdxandi
Wow, those are super slick. Thanks for sharing.

------
georgewfraser
I've experienced the problem of unwieldy controllers myself, but angular is
already such an intricate, opinionated framework that I can't imagine adding
another layer with its own DSL. Good code organization solves a lot of these
problems.

~~~
userbinator
I've noticed that particularly in web development there is this trend of
writing - and using - countless frameworks that add much more complexity with
little gain, and where the response to existing complexity is to... add more
of it. IMHO that doesn't seem like a very good way of doing things, since now
you have to learn not only JS, but also all these extra indirections piled on
top, to understand how your web application works. It's not doing any favours
for the browser that has to run all this code either. On the whole, this just
feels to me like an immensely wasteful way of doing things.

~~~
georgewfraser
Definitely true in general though angular in particular is SO GREAT that it is
worth it. But it certainly doesn't need MORE layers like the one in this post.

------
hotshothenry
Looks interesting, I might try it out on my next Angular project (starred it
to remember for the future).

As a side-note (don't mean to hijack this thread) but I always wondered why a
service doesn't exist that sits on top of GitHub that allows for
reviews/commentary beyond just issues on all these cool GitHub projects. There
are so many awesome projects that look really interesting and I want to
integrate into a project I'm working on but have no way of really knowing how
effective or relevant they are without actually trying it (which sometimes
works out but sometimes ends up being a waste of time). Just a thought, wonder
if anyone else here at HN sympathizes.

~~~
_zen
Search Twitter, /r/programming, HN, Stackoverflow, or Google for the Github
project and read opinions. Works 95% of the time. (Also bookmark this thread
and come back to it in a few days)

~~~
hotshothenry
That's definitely my flow right now -- unfortunately that works best for
bigger projects but less likely to find material on smaller projects you know?

------
solomone
I like this. One thing I like about is it how it sets up a canonical place to
init things.

The other nice effect is the use of the injector instead of the repeated list
of dependencies.

When not using coffeescript in angular, I could see making good use of this.
Thanks !

~~~
davej
It works really well with Coffeescript too. In fact it was written with
Coffeescript and internally it uses Coffeescript's `Class` syntax.

It was originally inspired by this gist:
[https://gist.github.com/elado/8138516](https://gist.github.com/elado/8138516)

~~~
solomone
I could see one annoyance being the lack of "fat arrow" in normal javascript
and trying to reference the services in a callback.

------
grumblestumble
There's a lot of conversation about the redundant injector syntax in this
thread. This is something that ngmin takes care of completely transparently.
There's really no need to worry about it in raw, uncompressed source code.
Other than that, this provides a nice way to enforce a certain set of
conventions, but I'm not completely sold on the quality of those conventions -
the most glaring thing being losing references to your watches. Reverse-
binding controllers to views through DOM selectors also has a bad code smell
IMO, feels a bit like reverting to jQuery madness. I prefer to do this through
routing or directives wherever possible.

~~~
solomone
ngmin isn't really a solution, it's a post processing transpiler hack. There's
lot of ways to format your js code so that ngmin does the wrong thing and
destroys working code. I wouldn't call the problem 'solved'. At least not
until angular 2.0 or a solution like this.

------
camus2
A more clever approach would be to be able to register controllers as services
through a classy service.I dont like the fact that you extend angular iteself
with a new method on the module object.

And then angular internals get updated and it breaks...

------
xwowsersx
This seems interesting. Definitely going to give it another look when I have
time to clean some things up in my app. The controller DEFINITELY do get
unwieldy after a while.

------
Bahamut
I guess this can clean logic flow in a controller, but here you end up with a
bloated object instead.

The biggest problem I see though is if you want to save a reference to the
unregister functions of the $watch callbacks.

Otherwise, this is a cool idea, although it falls a little short.

~~~
davej
> The biggest problem I see though is if you want to save a reference to the
> unregister functions of the $watch callbacks.

This is a valid criticism, thank you. I will try to put together a nice
solution for this.

Of course you can always register/de-register watchers the normal way inside
of the init method.

~~~
Bahamut
Yup, I'm aware - nice work on this so far!

------
Keats
Typescript classes work nicely with Angular controller I find. Coffeescript
ones too.

~~~
camus2
Afaik you cant declare anonymous classes in typescript,let alone wrapping them
in a closure.

No problem with Coffeescript.

    
    
        module.controller 'MainCtrl', class
            constructor:($scope,bar,baz)->
              $scope.message="foo"
            @$inject = ['$scope','bar','baz']
    

that's why i prefer the later.types or not.

~~~
Keats
I don't use anonymous classes for controllers so that's not an issue for me
but if you want to use them, I don't think there's a way to do it in
typescript

------
whalesalad
The fact that you can flip the entire page into Coffeescript mode is
BRILLIANT. Also, love the tooltips that come out of the code blocks.

