1
votes

I've been taking a stab at learning AngularJS lately, mildly succeeding at getting things to happen the way I want, and then I went back to refactor my code. I had this to start with:

window.App = angular.module('Plant', ['ngResource'])

App.factory 'Plant', ['$resource', ($resource) ->
  $resource '/api/plants'
]

App.controller 'PlantCtrl', ['$scope', 'Plant', ($scope, Plant) ->
  $scope.plants = Plant.query()

  $scope.totalCost = ->
    # code to sum up the #cost of all the plants

  $scope.addPlant = ->
    # code to create a new plant
]

Coming from a heavy Rails background, my first thought was to slim up the controller by moving the totalCost logic into the Plant factory. After all kinds of fiddling and endless reading about the difference between Services and Factories, The only working implementation I could find was:

  • Leave the Factory alone
  • Create a Service with all the model related methods I need
  • Make the Factory available to the Service
  • Make the Service available to the Controller

Here's the code:

App.factory 'Plant', ['$resource', ($resource) ->
  $resource '/api/plants'
]

App.service 'PlantService', ['Plant', (Plant) ->
  @all = ->
    Plant.query()

  @totalCost = (plants) ->
    # code to sum of #cost
]

App.controller 'PlantCtrl', ['$scope', 'PlantService', ($scope, PlantService) ->
  $scope.plants = PlantService.all()

  $scope.totalCost = ->
    PlantService.totalCost($scope.plants)

  $scope.addPlant = ->
    # code to create a new plant
]

Wasn't completely happy with this, but my controller was thinner and it'd had been way too long so I was ready to settle. I then realized I was using 1.0.6, and when I replaced my Angular files with the latest (1.2.7 at the time of writing), things stopped working, and I was shown the all too familiar ...has no method all().

If anyone has suggested refactorings, readings, or trolling insults on how I'm doing this all wrong - I'm all ears. Primary goal is to move model related logic out of my controller, on the hunt for the right implementation.

1

1 Answers

0
votes

Two things I know off hand that have changed between those versions. You now need to include ng-route.js separately and have your main module depend on ngRoute if you are using the built in routing. Secondly if you're using ng-bind-html you'll need to change that to ng-bind and use $sce.trustAsHtml() on the string you plan to show in there.

For a more thorough check on changes go to the changelog here:

https://github.com/angular/angular.js/blob/master/CHANGELOG.md

Check the breaking changes sections from 1.0.6 to 1.2.7 to find anything you might encounter in the upgrade.