function( x, y, z ){
...
}
this.property( x )
var x = {
prop: true
}
( x, y, z ) ->
...
@property x
x =
prop: true
// First Steps...
<a ng-click=" open = !open ">Toggle</a>
<div ng-show=" open ">Content!</div>
// Later Steps...
<a ng-click=" userOpen = !userOpen ">Toggle</a>
<a ng-click=" carOpen = !carOpen ">Toggle</a>
<a ng-click=" animalOpen = !animalOpen ">Toggle</a>
<a ng-click=" insaneOpen = !insaneOpen ">Toggle</a>
module.controller 'Person', ($scope, mySocket, $http, Person) ->
$scope.person = Person.get()
$scope.save = (data) ->
...
$http(...)
$scope.$on 'socketMessage', (event) ->
if event.object != 'Pet' return
switch event.type
when 'CREATE', 'GET'
$scope.pet = event.data
when 'UPDATE'
...
when 'DELETE'
delete $scope.pet
module.factory 'BaseObject', ($q) -> class BaseObject constructor: (initData) -> angular.extend( @, initData ) module.factory 'PersonObject', (BaseObject) -> class PersonObject extends BaseObject constructor: (initData) -> super(initData) ... remove: -> ... save: -> @id && @create() || @update() create: -> ... update: -> ... module.factory 'AppObject', (BaseObject) -> class AppObject extends BaseObject
... # Returns singleton instance instead of class return new AppObject()
# Resolved in Router
module.controller 'Person', ($scope, person) ->
$scope.person = person
<form ng-submit="person.save()">...</form>
<a ng-click="person.getPets()">Show Pets</a>
<h2>Pets:</h2>
<div ng-repeat="pet in person.pets">
<h3>{{pet.name}}</h3>
<a ng-click="pet.getTricks()">List Tricks</a>
<ul>
<li ng-repeat="trick in pet.tricks">{{trick.name}}</li>
</ul>
</div>
# Create new Bacon streams
socketStream = new Bacon.Bus()
queryStream = new Bacon.Bus()
# Subscribe to socket events
mySocket.onmessage = ( event ) ->
$rootScope.$apply ->
# Broadcast new stream event
socketStream.push ( event )
# Subscribe to query requests
queryStream.onValue ( event ) ->
mySocket.send( JSON.stringify( event ) )
class AppObject extends BaseObject
constructor: ( @downStream, @upStream ) ->
query: ( data ) ->
@upStream.push( data )
app = new AppObject( socketStream, queryStream )
class PersonObject extends BaseObject
constructor: ( @downStream, @upStream, initData ) ->
# All events on this object and deeper filtered to this project object
@downStream = @downStream.filter (event) ->
return ( event.projectId == @id )
# All queries get decorated with context
@upStream.onValue (event) ->
event.projectId = @id
class PersonObject extends BaseObject
getPets: ->
...
getPet: (id) ->
if !@pets
@getPets().then ->
return @pets[id]
else
@query({ type: 'READ', object: 'Pet', id: id }).then (petData) ->
# spins up a new instance and passes the project streams
return @pets[id] = new PetObject(@downStream, @upStream, petData)
class PetObject extends BaseObject
constructor: ( @downStream, @upStream, initData ) ->
super( @downStream, @upStream, initData )
# All events on this object and deeper filtered to this project object
@downStream = @downStream.filter (event) ->
return ( event.projectId == @id )
class PersonObject extends BaseObject
constructor: ( @downStream, @upStream, initData )
@super( @downStream, @upStream, initData )
@downStream.filter( (event) ->
return (event.type == 'UPDATE' && event.object == 'Project')
).onValue (event) ->
angular.extend(@, event.data)
@downStream.filter( (event) ->
return (@pets && event.type == 'CREATE' && event.object == 'Pet')
).onValue (event) ->
@pets[event.data.id] = new PetObject(@downStream, @upStream, event.data)
$stateProvider.state 'top',
url: '/top/{topId}' # /top/123
template: '<div> ... <ui-view></ui-view> ... </div>'
controller: ($stateParams) ->
$stateParams.topId
$stateProvider.state 'top.middle',
url: '/middle/{middleId}' # /top/123/middle/123
template: '<div> ... <ui-view></ui-view> ... </div>'
controller: ($stateParams) ->
$stateParams.topId
$stateParams.middleId
$stateProvider.state 'bottom',
url: '/bottom/{middleId}' # /top/123/middle/123/bottom/123
parent: 'top.middle'
template: '<div> ... <ui-view></ui-view> ... </div>'
controller: ($stateParams) ->
$stateParams.topId
$stateParams.middleId
$stateParams.bottomId
<nav ui-view="nav"></nav>
...
<ui-view></ui-view>
$stateProvider.state 'top',
url: '/top/{topId}' # /top/123
template: '<div>...<ui-view></ui-view>...</div>'
controller: -> ...
$stateProvider.state 'top.middle',
url: '/middle/{middleId}' # /top/123/middle/123
template: '<div> ... <ui-view></ui-view> ... </div>'
views:
'': # un-named <ui-view>
template: '<div>Body</div>'
controller: -> ...
'nav@': # nav <ui-view> at the top level
template: '<h1>Middle</h1>'
controller: -> ...
$stateProvider.state 'person',
url: 'person/{personId}'
resolve:
person: ( $stateParams, AppObject ) ->
return AppObject.getPerson( $stateParams.personId )
controller: ( person ) ->
...
$stateProvider.state 'person.pet',
resolve:
pet: ( $stateParams, person ) ->
return person.getPet( $stateParams.petId )
$stateProvider.state 'person.pet.tricks',
resolve:
tricks: ( pet ) ->
return pet.getTricks()
controller: ( tricks, person ) ->
...
$stateProvider.state 'person',
url: '/person/{personId}'
resolve:
person: ( $stateParams, AppObject ) ->
return AppObject.getPerson( $state.personId )
onEnter: ( person ) ->
person.open()
onExit: ( person ) ->
person.close()
angular.module('myApp.directives')
angular.module('myApp.models')
angular.module('myApp.Core')
angular.module('myApp.Person')
angular.module('myApp.Car')
angular.module('myApp.Person.Child')
angular.module('myApp.Animal.Dog')
angular.module('myApp.Admin') // 'mixin' module
# Wrapper module module = angular.module( 'myApp.Person', [ 'myApp.Person.Core', 'myApp.Person.Child', 'ui.utils', 'ui.bootstrap' ] ) # Bootstrapping Module core = angular.module( 'myApp.Person.Core', [ 'ui.router', 'myApp.Core', # BaseObject 'myApp.Animal.Pet' # PetObject ] )
core.config ($stateProvider) -> ... core.factory 'PersonObject', (PetObject) -> module.directive( 'dash-person', ... ) module.controller( 'People', ... )
# ChildObject must be defined
module.factory 'PersonObject', ['BaseObject', 'ChildObject']