1

I have a lot of jQuery background and am currently getting into angular.
So far I have resisted the urge to include jQuery to get things done the way I used to.
I would like really learn to do things the angular way.

Here are some things I ran across and I would really like the opinion of some angular professionals on them:

  1. Adding user interactions.
    Standard scenario: If the user does this, do that.
    Should I create directives for each case or add methods to the controller?
    How do I decide wether to make a directive out of it or just a controller method?

  2. Adding the same functionality to multiple elements
    Presume I have a bunch of divs spread out over the page, or even just several cols of a table.
    In jQuery if I wanted to do something, when the user clicks on any of them I would just do $('div').click(...) or $('#mytable th').click(...)
    In angular the only way I know how to do this is the ng-click directive, which results in very verbose code, when adding this directive to every single element.
    Especially since I thought angular was supposed to make code more readable I was wondering if there is a better solution to that.

  3. Separation of Code
    One of the things I like about angular is the effort to keep html in html files and the js in js files. This was actually one of the things that most annoyed me with jQuery.
    But the way directives are set up sort of contradicts this. Here you define some template html code (or link a template file). The same goes for user interaction handlers (i.e. user clicks this -> display that message).
    So in the end I end up again sifting through code to find out where that particular piece of html code comes from. Am I missing something here?

  4. MVC
    In most of the examples out there the model is defined inside of the controller.
    Shouldn't it be defined somewhere else for true MVC separation? What about for example always creating a service for the model, since often at least parts of the model are loaded by services anyway? Or am I overstepping the mark here?

  5. app.js
    This is more of a side note: I find it confusing that for both node and angular the convention is to call the main file 'app.js'. If I have both files open in my editor I have to click through them to see which is which. I know I can name then however the hell I want but as I said I'd like to do things right and am just wondering if this never bothered anyone else... Maybe angular should consider enforcing the convention "app_ng.js" or something...?

Please post your thoughts as answers, not comments, for readability purposes.

thank you,
Jan

Jan Paepke
  • 1,997
  • 15
  • 25
  • Most of your questions are very broad. Try to give concrete examples for each of your concerns. Usually, in the process of producing such an example, you are already able to clear much of the confusion. – Domi Jul 07 '14 at 09:09
  • Yes, they are broad, because they are more questions of principle than related to a specific example. – Jan Paepke Jul 07 '14 at 09:15
  • 1
    But that is not what Stackoverflow is about. Questions of principle, style etc. are too subjective and thus easily rejected (despite the fact that almost all of the most popular questions are actually just that). Nevertheless, without examples, it is just much more difficult to help you because everyone will interpret your questions slightly differently. – Domi Jul 07 '14 at 09:17
  • Maybe this post may help you: http://stackoverflow.com/questions/14994391/how-do-i-think-in-angularjs-if-i-have-a-jquery-background – lex82 Jul 07 '14 at 09:19
  • I hear you @Domi. Still I am unsure how I could even give an example that would help. For 1. the question is exactly in what case to use what, so how can I give an example? 2 has an example. 3 is pretty specific and 4 and 5 don't really need an example. I am aware that the answers would be subjective, but that's why I was hoping that some angular Pros would chime in. – Jan Paepke Jul 07 '14 at 09:32
  • @lex82: Thx. I actually already read that one. – Jan Paepke Jul 07 '14 at 09:32
  • Did you read the developer guide (conceptual overview in particular)? https://docs.angularjs.org/guide – Wottensprels Jul 07 '14 at 09:37
  • Not in depth to be honest. I will give it another go. – Jan Paepke Jul 07 '14 at 09:42
  • The mistake that you are making is "How can I translate my jQuery into Angular", you should completly forget about jQuery. Wrting Angular like jQuery will make your code untestable and cluttered. That was my worst mistake, and I releasied it when my app become big and fat. – Michał Lach Jul 07 '14 at 10:41
  • Thanks Michal. I do realize that and this is exactly why I am trying to find out how to do it the right way. – Jan Paepke Jul 07 '14 at 10:45

1 Answers1

1
  1. User interactions
    These can be done both using directives and controllers. there is no strict rule on when to use controllers or when to use directives. Often small one-off interaction code is done in controllers, but more complex interaction logic is done in directives. Reusable interaction logic should always be done in directives. Same as DOM manipulation. That also should be done in directives.

  2. Multiple elements, same functionality
    Often when this is the case you should be/are generating those elements anyway. e.g. using ng-repeat. Which reduces this to changing 1 line. In the situations where that is not the case, you could make a parent directive that checks the children. However, it might also be the case that you just need a custom directive. e.g. multiple divs doing a similar thing all over the page? Perfect example of something that should be a directive. Then you can either use the template in the directive or use more specific logic in the directive link or controller function.

  3. html-js seperation
    Most directives use templateUrl to do the templates which keeps them in partial html pages. A few libraries pre-seed the $templateCache on run so that angular doesn't need to request those templates. (also allows for customization by replacing the $templateCache entry.) When looking at the DOM in the dev tools it might not be completely clear where that html came from, but if you look up in the DOM tree, you will find the directive that is responsible for it. In older versions of angular it was possible for directives to use "replace: true" to replace the actual directive in the DOM, but in 1.3 that is deprecated. So, now you have the directive. Next is to actually find where the directive is specified. This depends greatly on you project layout, but with good project layouts it would be as simple as just browsing to the correct folder. e.g. bla-date-picker: prefix is bla, so it is in the blabla module. open blabla module, find a directives folder. open directives folder, find datePicker. Then in the directive definition you see if it uses the template directly or if uses a template html file.

    Regarding code that lives in controllers, you should already know which controller you are in. For example by again looking at the DOM tree and seeing which controllers are the parents. Then you only have to find the correct controller file(again, this depends on your project layout. A good layout will make it easy to find). With a good DOM layout the object will at most have 2-3 controller parents and most often the lowest controller in the tree at that point will have the code you are looking for.

    Do note however that angular does not place a whole lot of restrictions on you. So you can still make a mess of the project and make stuff hard to find(e.g. defining everything in 1 file, use $rootScope, use 100s of nested controllers, etc.). It is up to the developer to make sure those things don't happen. In a good project it should be easy and straightforward to find things. In a bad project, well....

  4. MVC
    Angular is not an MVC framework. You can use it for MVC but you don't have to. Often examples are kept small which means it doesn't use best practices for brevity sake. So yes, in general you would want to define the models in services(or as services).

  5. App.js
    You don't need to use angular with node. Also, you can name it whatever you want. For example in my projects I don't have an app.js for angular, but only a file named after the app module. And even better, I have 2 separate projects. 1 back-end(which is mostly API) and 1 angular front-end project. Because with angular the need for a templating engine is almost non-existant you can serve all angular files as static. Meaning that it is relatively easy to separate it to its own project.

Zerot
  • 196
  • 2
  • Thanks, this is what I was hoping for. Allow me some follow ups: 1/2: Example: The user clicks on an area and an input field should be focussed. Option A: Create a controller method, that finds the input and focusses it and attach the method to the area. Option B: Create a directive, attach it to the input field and focus it whenever a model is changed or an event is called? 5: I know i can name it and I know i don't HAVE to use it with node. I was just wondering about the conventions. Would another programmer easily find your main files by looking at the file structure? – Jan Paepke Jul 07 '14 at 12:13
  • 1
    regarding your focusing: How about a combination of a directive and the controller. Have the directive watch a specific variable(either using $watch or attr.$observe) and then set that variable with the controller. To make it even more reusable you could do something like '' which will focus when the var "varname" is set to "state". There are a lot of different solutions for it, however, the actual focus logic(i.e. calling focus on element) should always be done in a directive because that is part of the DOM. – Zerot Jul 07 '14 at 14:27
  • 1
    and regarding the app.js: As long as the project structure is clear, it should be easy to find. when using ng-app in the application you should always give it the main module name. After which you can store that module the same way you store every module. – Zerot Jul 07 '14 at 14:27
  • Thanks. I actually implemented the focus logic just as you suggested. Good to see that I seem to start to get it. ;) Thanks a lot for your thoughts, they helped me a great deal. – Jan Paepke Jul 07 '14 at 14:32