Skip to content

Instantly share code, notes, and snippets.

@ajhekman
Last active August 29, 2015 14:00
Show Gist options
  • Save ajhekman/11058943 to your computer and use it in GitHub Desktop.
Save ajhekman/11058943 to your computer and use it in GitHub Desktop.
MH Blog AngularJS Property Model
angular.module("app", [ "ngRoute" ]).run ($rootScope, UserService) ->
#Avoid $rootScope if you can. User and Session info is about all that should go on $rootScope.
#UserService.getUserByID(1).then (user)->
# $rootScope.user = user
<div id="home" class="row" ng-controller="homeCtrl">
<h1>Hello {{userName()}} (with controller null checking)</h1>
<h1 ng-if="user">Hello {{user.get('fullName')}} (with ng-if null checking)<h1>
</div>
angular.module("app").controller "homeCtrl", ($scope, UserService)->
$scope.userName = ()->
if $scope.user? then $scope.user.get('fullName') else ""
# This works for this example, but typically you would want your
# logged on user either on $rootScope, or on a bag-of-bits angular service.
UserService.getUserByID(1).then (user)->
$scope.user = user
angular.module('app')
.factory "PropertyModel", ($log) ->
class PropertyModel
@defaults: ->
angular.copy( {} )
constructor: (properties)->
@update(properties)
accessors: {}
# Pass in string of property name
# returns property value
get: (propName) ->
@_getOrCallProperty propName
# Pass in string of property name and value, or if complex property; values
set: (propName, values...) ->
setterMethod = @accessors["set_#{propName}"]
if setterMethod?
setterMethod.apply @, values
else
if values.length > 1 then throw "Cannot provide multiple values for a singular property"
@properties[propName] = values[0]
# Pass in an object of key/value pairs to use as properties.
# This will reset the properties of this object to those passed in
# plus any default properties defined on the constructing class.
update: (properties={}) ->
unless angular.isObject properties then throw "'#{@.constructor?.name}' properties must be contructed with an object '{}'"
@properties = @properties || {}
unless _.isEqual(angular.copy(@properties), properties)
defaults = this.constructor.defaults?() || {}
@properties = _.extend(defaults, properties)
_getOrCallProperty: (propName) ->
readerMethod = @accessors?["get_#{propName}"]
if readerMethod?
readerMethod.apply @
else if @properties.hasOwnProperty(propName)
@properties[propName]
else
$log.error "PropertyNotFound: '#{propName}' on #{@.constructor?.name} Model"
return null
angular.module("app").config ($routeProvider, $locationProvider) ->
$locationProvider.html5Mode true
$routeProvider.when "/home",
templateUrl: "home.html"
$routeProvider.otherwise redirectTo: "/home"
angular.module('app')
.factory "User", (PropertyModel) ->
class User extends PropertyModel
accessors:
get_fullName: ()->
title = @get('title')
unless title == "" then title = title + " "
"#{title}#{@get('firstName')} #{@get('lastName')}"
get_gender: ()->
if @properties.gender? && @properties.gender != "" && @properties.gender != "unknown"
@properties.gender
else if @properties.title? && @properties.title != ""
if _.contains ['Mr.', 'Mister'], @properties.title
"male"
else if _.contains ['Ms.', 'Miss.', 'Mrs.'], @properties.title
"female"
else
"unknown"
else
"unknown"
get_isTaxable: ()->
_.contains ['MI', 'OH', 'FL'], @properties.addressState
angular.module('app')
.service "UserService", ($http, User, $q) ->
genericErrorCallback:(response)->
console.log "error", response
$q.reject(response)
getUserByID: (id) ->
success = (response)->
new User response.data
$http.get("/user/#{id}").then(success, @genericErrorCallback)
blankUser: ->
new User {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment