Insecurities about 'the angular way' [closed] - javascript

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
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:
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?
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.
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?
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?
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

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.
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.
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....
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).
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.

Related

best practice controller / services

I have built an Angular app that consumes data from different sources (SharePoint lists). I setup a controller for each source.
What is the best practice for this? Use only one controller for the app and different services? Or one service and one controller? Or multiple services and controllers?
In the app I do not use routing.
First I'd recommend reading these articles. Also, go through their angular implementation and see how they've achieved some of their effects. It will throw you in a world of problems that you'll feel like "Why? I mean, why? why did I ever got into this mess?" But, grit your teeth and get through it. Then you'll see how much you can achieve. Learning Angular JS is a never-ending cycle of this.
angularjs-best-practices-directory-structure
Angular Style Guide
Advanced Design Patterns and Best Practices
The Top 10 Mistakes AngularJS Developers Make
Ok, and to answer your question: your way isn't wrong.
But controllers are not designed to be used like that. Controllers are a unit of code which co-ordinates your data into the UI, handle UI events, etc. generally of a certain view - i.e. a portion of your UI (navigation bar, home page, edit form, etc.). Of course this can be your entire page as well. But it's best to break it down so that it's easier to manage.
Use services for what you described. Create a service for each data source or type of data (users, equipment, roles, etc.). I recommend that latter, since sometimes you need to pull data from multiple ends and tie them together. This can be done inside your controller as well, but having services will enable you to re-use that functionality in another part of your application.
To summarize a long answer, I'd say go through these articles, code and tips. Then build a structure that will help build your application. Just don't over-engineer it.
I would say: use a controller for every "piece" of HTML in your app, (and it depends on the scale of your app how big that piece is, it could be just one controller if your app is really small). And use a service for each data source. Then you can use the services your need in your controllers. You could also use one service if you don't need a lot of behavior. It all depends on how big your application will be.

Improve AngularJS performance on multiple levels

I'm writing a complex, multi-component app using AngularJS. Currently, the main components are ready and I want to improve the performance of the app.
After a short investigation on the field, I found some very useful resources:
11 Tips to Improve AngularJS Performance
Improving AngularJS wep app performance example
AngularJS Performance in large applications
Anyway, I need some additional advises on a few topics:
1. Script and Services/Factories loading
currently, all scripts are loaded at the bottom of the <body></body> tag inside index.html. Therefore, when the user loads directly a ui-route or we simply reload given page, all the scripts are loaded again. I want to load the scripts only in states that use the given script.
Services/Factories/etc. are loaded the same way. This causes pages which do NOT need the given e.g. Service to load it and this is slowing the performance, because of the big data load. I need to initialize/load them only when they are needed in the current state.
2. Translation/Localization
I'm using Angular Translate - i18n Reference, but when I'm translating the page elements I must use e.g. <button>{{btnName | translate}}</button. This technique and the overall usage of filters is pointed as one of the biggest performance drawbacks. The page has a lot of elements so this really might slow the loading. Is there any better solution or any workaround?
3. Overall
I've read the multiple threads on ng-repeat and its track by feature, so I assume it done, but I'm still not 100% sure that I understand the $digest ($apply) cycles correctly.
I read some comments that we should "avoid bind anything directly to a function", but I don't quite get it.
Any additional comments or advises relative to AngularJS and its performance are welcome!
Thank you :)
Reading the above, it looks like you already tried to optimize AngularJS itself. However, there is no mention of optimizations on your build process. I guess it would be wise for you to investigate Grunt or Gulp. With these tools you can concatenate and minify all your JavaScript to a single minified file. This way you only have a one-time payload while initialising your site.
Check this https://medium.com/#dickeyxxx/best-practices-for-building-angular-js-apps-266c1a4a6917

Deploying angular apps without displaying bindings on the view

I want to ask whether there is a way to deploy the angular apps i.e. (modules, controllers, factories) and the bindings so that when users would inspect it or view page source on their browsers they're shown the html and not the bindings like for example {{persons.name}}, {{persons.email}}.
Even when we use ng-bind or ng-bind-template we have our model objects displayed in the code inspection or view page source views of browser.
Understandably the framework it self is based on Java script to start with and the scripts are required on the page, but my question is that is there a way to hide the underlying model architecture in the controller or factories written for some app ?
Can we use some technique for building our scripts and executing them on run time instead while our app initializes and not make code (in our scripts) and bindings (in our html) observable to the users ?
I have done a bit of searching and haven't yet found a suitable solution, most of the articles and references regarding Angular point towards it's core concepts instead.
I have recently started working on Angular so I'm trying to do things the right way as I have a jQuery background.
It sounds like you are wanting to know if you can pre-render angular. While there are some technologies that do this, it is for the sake of search engine optimization, not for end-user use. This is because AngularJS is run client-side. If you have to pre-render it, you completely defeat the purpose of having it (honestly, you should just go with some other technology that does server-side rendering).
If you want to 'hide' your angular code, about all you can do there is minify it with something like uglify. This will make your angular code incredibly difficult to work with, and smaller for the end-user to download. There is an additional 'mangle' capability that uglify offers, but my understanding is that it is difficult or impossible to get it to work with angular due to some of angular's peculiarities regarding dependency injection.
To hide bindings like {{persons.name}} during page loading just add the ng-cloak class to your container (don't forget to add angular css file to your page), Angular will display it when everything is loaded.
You can't, as far as I know, hide your directive in your html code, but honestly I don't think it's really a problem, in front-end development your code is anyway always observable.
Short Answer: No
its not possible to hide the underlying model since Javascript is interpreted at client side it will always be possible to view the underlying model.
However you can also view the interpreted version of your HTML with firebug or any other debugging tool

AngularJS, Tabbed Forms and Directives

I'm building a view like the one below but have some doubts on how to do it. I don't want to make unneccessary calls to the service but I want to keep things simple.
My thoughts
The small piece of basic information with name etc will always be visible. I guess this little piece would be a nice directive? (never wrote one myself)
For the tabs I'm not sure how to do it at all? Will I make every tab a view with it's own controller (and a service that will fetch specific data for that view) or should I fetch a huge customerobject and put in some storage or..?
Would appreciate your thoughts and answers about best practice, regards!
I think you can use angular-ui-bootstrap directives, it includes some useful directives.
http://angular-ui.github.io/bootstrap/

javascript frameworks: What are UI bindings and composed views?

I'm reading this:
http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/
I'm using backbone.js. I love it, though it requires too much boilerplate. Anyway.
The author of the post seems to put great importance on UI-bindings and composed view.
I think I know the basic advantage of ui bindings, you can change small parts of the view as the model changes without re-rendering the entire view. I don't necessarily see the point though. If your view is huge maybe you should make smaller views? I've seen knockoutjs's code and it's littered with ugly data-bind stuff. How does emberjs handle it? Is there an example?
I have no idea what he means by composed views, could someone elucidate?
Composed Views - Like all software developers, I enjoy creating modular reusable code. For this reason, when programming UI, I would
like to be able to compose views (preferably at the template layer).
This should also entail the potential for a rich view component
hierarchy. An example of this would be a reusable pagination widget.
Is there an example?
Thanks
Edit:
Would this help make something like composed Views?
https://github.com/tbranyen/backbone.layoutmanager
Composed views are used to divide the view into small blocks which can be reused or adapted to different scenarios.
For example, in a form where you are editing a user, you could create a view for the address field and just call it from the main page/template. The author mentions pagination as an example too, in this case you could create a model that knows how to handle retrieving data as you switch between pages and just apply it to a table in your page.
Regarding the "ugly" data-binding code, backbone needs to know how to attach itself to the existing markup and how to modify it when an event occurs.
Maybe this example will help:
http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/
Traditional web pages are monolithic. User calls a page and server constructs the page and browser renders it. Here author is referring to breaking down that kind of code in to a set of views. So your page is made up of multiple parts. And each part gets rendered and updated independently. Or one model change can trigger a series of updates on some or all parts.
Basically this allows you to create 'desktop' kind of applications on web. And you don't have to resort to iframe hacks to do this.
Gmail and Google Reader are good examples of web applications built with composed views.
I created LayoutManager for Backbone.js because I too wanted to composite views.
http://tbranyen.github.com/backbone.layoutmanager/
Let me know if you find this approach helpful.
It sounds to me like the author is talking about server-side code here. Building a system of reusable page templates, that generate pages from a common set of widgets, html snippets, etc...
Apache's Tiles is one way of doing this.

Categories

Resources