1

I am trying to get my head around how to better structure my angularjs applications by not overloading my controllers with too much logic. I feel like I have read just about every article on the subject but was hoping someone might be able to provide advice based on a specific example. I have put the requirements below for a job listing (as in jobs for a service company) screen and the functionality required.

Requirements:

  • Jobs are listed in a table and contain the following columns: id, customer, value ($), due date
  • Data is coming from a backend api (laravel/php) which provides a json array of objects with nested related objects and array of objects. Data is raw e.g. value ($) is 123.23 and due date is 2015-03-09.
  • The screen contains several filters for selecting a customer from a drop down list/autocomplete or selecting a date range for due date. Filtering is done server side, and server expects query params with a filter object e.g. filters={due_date_from='2015-03-07', due_date_to='2015-03-09',customer_id=123}
  • Filters are only applied when the user clicks on a filter button
  • Each column is sortable and sorting is done server side, so server expects query params with a sort object e.g. sort=[{by:'due_date', dir:'asc'}, {by:'customer_id',dir:'desc'}]
  • 25 jobs per page, paging is done server side e.g. page=2
  • Where jobs are overdue, the row should be red
  • The state of filters, paging, sorts should be stored in the URL and read upon initialisation.
  • A reset button should clear all filters

I am using the Restangular 3rd party module for pulling data from the server side and have used the extendModel methods to added helper functions such as isOverdue() which returns true/false.

Currently I have created the following properties and methods in my JobsListController.

$scope.jobs = [];
$scope.filters = [];
$scope.sorts = [];
$scope.loadData = function(){}; //build data packet to send to server
$scope.sort = function(); // checks if column is currently sort in order to reverse direction
$scope.reset = function(){}; //clears filters, sorts and paging to send to server

In my html I have the following things:

<input type="date" ng-model="filters.due_from" />

<td><a on-click="sortBy('customer_id')"></td>

Ultimately I think my question is, should I be creating a service/factory called JobsListModel rather than having all this functionality in the controller?

2

I'll speak out of my own little experience with AngularJS. I would definitely not say that that's a lot of logic, and anyway it seems to be all dealing with the server side API, where the business logic is, I suppose, so it's all view logic. It seems perfectly fine to me.

If you're worried about having too much logic, anyway, I would really consider adding some automated tests.

0

Here are my 2 cents from an AngularJS project I've been handling these past 6 months. While I'm in no way an expert in Angular, I did found out issues and uncovered some bad practices I've tended to do (and somewhat fixed along the way).

Controllers are a problem because they tend to get rally fat, rally fast. If your controller is passing the 500 lines mark (or you're feeling it's gonna pass really soon) you should stop everything and refactor your code. a couple of things I did were

  1. separate service (remote data fetching) and controller (displaying data on view) logic, this is the first thing you should do when writing your app, if you have error handling in you http calls, send them to the service. that should shave off a couple of lines in your controllers. you should decouple your code either by logic or by job types.

  2. you can assign more than one controller per view. In my project I had to write a dashboard that fetches data to several charts in a view, and to populate ~5 log tables, all in the same view. I've separated the dashboard view to 2 controllers, one to handle the charts and the other for the log tables. I may separate the charts controller even more in the future.

  3. filters, no matter how small they should be in their own files, every new module you assign to your project should have it's own file, it keeps things organized

  4. I often found myself doing doing complex validation in my controllers (an example being to validate an input field as a valid i.p. address), you can instead, write a directive and migrate that logic over there.

  5. style guides are your best friends! here are a couple of good ones, this one and that one

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.