Skip to content

Commit f8cc501

Browse files
committed
reorganised the structure
1 parent 31ad5e8 commit f8cc501

File tree

1 file changed

+109
-76
lines changed

1 file changed

+109
-76
lines changed

Diff for: README.md

+109-76
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
* [Others](#others)
3737
* [Module Pattern](#module-pattern)
3838
* [Data Mapper](#data-mapper)
39+
* [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)
3940
* [References](#references)
4041

4142
<!--endtoc-->
@@ -794,94 +795,38 @@ will produce the same result as the one above. The main difference here is that
794795
795796
![Observer](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/observer.svg "Fig. 7")
796797

797-
##### About
798-
Below is an example taken from https://github.com/greglbd/angular-observer-pattern. This is an angular factory which reflects the Observer Pattern it works well with the ControllerAs method of working as it can be much more efficient that $scope.$watch and more specific to a unique scope or object than $emit and $broadcast when used correctly.
799-
800-
**Use Case:** You would use this pattern to communicate between 2 controllers that use the same model but are not connected in anyway
801-
802-
##### Methods
803-
804-
function adds a listener to an event with a callback which is stored against the event with it's corresponding id.
805-
```
806-
_observerService.attach = function(callback, event, id)
807-
```
808-
809-
810-
function removes all occurences of one id from all events in the observer object
811-
```
812-
_observerService.detachById = function(id)
813-
```
814-
815-
816-
function removes all occurences of the event from the observer Object
817-
```
818-
_observerService.detachByEvent = function(event)
819-
```
798+
There are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see [Scope](#scope)). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes.
820799

800+
Each AngularJS scope has public methods called `$on`, `$emit` and `$broadcast`. The method `$on` accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the `Observer` interface (in JavaScript the functions are first-class, so we can provide only implementation of the `notify` method):
821801

822-
removes all callbacks for an id in a specific event from the observer object
823-
```
824-
_observerService.detachByEventAndId = function(event, id)
802+
```JavaScript
803+
function ExampleCtrl($scope) {
804+
$scope.$on('event-name', function handler() {
805+
//body
806+
});
807+
}
825808
```
826809

810+
In this way the current scope "subscribes" to events of type `event-name`. When `event-name` is triggered in any parent or child scope of the given one, `handler` would be called.
827811

828-
Notifies all observers of a specific event, can pass a params variable of any type
829-
```
830-
_observerService.notify = function(event, parameters)
831-
```
832-
812+
The methods `$emit` and `$broadcast` are used for triggering events respectively upwards and downwards through the scope chain.
813+
For example:
833814

834-
##### Controller Example
835-
Below example shows how to attach, notify and detach an event.
836-
```
837-
angular.module('app.controllers')
838-
.controller('ObserverExample',ObserverExample);
839-
ObserverExample.$inject= ['ObserverService','$timeout'];
840-
function ObserverExample(ObserverService, $timeout) {
841-
var vm = this;
842-
var id = 'vm1';
843-
ObserverService.attach(callbackFunction, 'let_me_know', id)
844-
845-
function callbackFunction(params){
846-
console.log('now i know');
847-
ObserverService.detachByEvent('let_me_know')
848-
}
849-
850-
$timeout(function(){
851-
ObserverService.notify('let_me_know');
852-
},5000);
815+
```JavaScript
816+
function ExampleCtrl($scope) {
817+
$scope.$emit('event-name', { foo: 'bar' });
853818
}
854819
```
855-
Alternative way to remove event
856820

857-
```
858-
angular.module('app.controllers')
859-
.controller('ObserverExample',ObserverExample);
860-
ObserverExample.$inject= ['ObserverService','$timeout', '$scope'];
861-
function ObserverExample(ObserverService, $timeout, $scope) {
862-
var vm = this;
863-
var id = 'vm1';
864-
ObserverService.attach(callbackFunction, 'let_me_know', id)
865-
866-
function callbackFunction(params){
867-
console.log('now i know');
868-
}
869-
870-
$timeout(function(){
871-
ObserverService.notify('let_me_know');
872-
},5000);
873-
874-
// Cleanup listeners when this controller is destroyed
875-
$scope.$on('$destroy', function handler() {
876-
ObserverService.detachByEvent('let_me_know')
877-
});
878-
}
879-
```
880-
**Public Repository to get you started**
881-
https://github.com/greglbd/angular-observer-pattern
821+
The scope in the example above, triggers the event `event-name` to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event `event-name`, would be notified and their handler callback will be invoked.
822+
823+
Analogical is the case when the method `$broadcast` is called. The only difference is that the event would be transmitted downwards - to all children scopes.
824+
Each scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event).
882825

883826
In the JavaScript community this pattern is better known as publish/subscribe.
884827

828+
For a best practice example see [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)
829+
885830
#### Chain of Responsibilities
886831

887832
>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.
@@ -1146,6 +1091,94 @@ And the following partial:
11461091
</div>
11471092
```
11481093
1094+
### Observer Pattern as an External Service
1095+
1096+
##### About
1097+
Below is an example taken from https://github.com/greglbd/angular-observer-pattern. This is an angular factory which reflects the Observer Pattern. It works well with the ControllerAs method of working as it can be much more efficient that $scope.$watch and more specific to a unique scope or object than $emit and $broadcast when used correctly.
1098+
1099+
**Use Case:** You would use this pattern to communicate between 2 controllers that use the same model but are not connected in anyway
1100+
1101+
##### Methods
1102+
1103+
function adds a listener to an event with a callback which is stored against the event with it's corresponding id.
1104+
```
1105+
_observerService.attach = function(callback, event, id)
1106+
```
1107+
1108+
1109+
function removes all occurences of one id from all events in the observer object
1110+
```
1111+
_observerService.detachById = function(id)
1112+
```
1113+
1114+
1115+
function removes all occurences of the event from the observer Object
1116+
```
1117+
_observerService.detachByEvent = function(event)
1118+
```
1119+
1120+
1121+
removes all callbacks for an id in a specific event from the observer object
1122+
```
1123+
_observerService.detachByEventAndId = function(event, id)
1124+
```
1125+
1126+
1127+
Notifies all observers of a specific event, can pass a params variable of any type
1128+
```
1129+
_observerService.notify = function(event, parameters)
1130+
```
1131+
1132+
1133+
##### Controller Example
1134+
Below example shows how to attach, notify and detach an event.
1135+
```javascript
1136+
angular.module('app.controllers')
1137+
.controller('ObserverExample',ObserverExample);
1138+
ObserverExample.$inject= ['ObserverService','$timeout'];
1139+
function ObserverExample(ObserverService, $timeout) {
1140+
var vm = this;
1141+
var id = 'vm1';
1142+
ObserverService.attach(callbackFunction, 'let_me_know', id)
1143+
1144+
function callbackFunction(params){
1145+
console.log('now i know');
1146+
ObserverService.detachByEvent('let_me_know')
1147+
}
1148+
1149+
$timeout(function(){
1150+
ObserverService.notify('let_me_know');
1151+
},5000);
1152+
}
1153+
```
1154+
Alternative way to remove event
1155+
1156+
```javascript
1157+
angular.module('app.controllers')
1158+
.controller('ObserverExample',ObserverExample);
1159+
ObserverExample.$inject= ['ObserverService','$timeout', '$scope'];
1160+
function ObserverExample(ObserverService, $timeout, $scope) {
1161+
var vm = this;
1162+
var id = 'vm1';
1163+
ObserverService.attach(callbackFunction, 'let_me_know', id)
1164+
1165+
function callbackFunction(params){
1166+
console.log('now i know');
1167+
}
1168+
1169+
$timeout(function(){
1170+
ObserverService.notify('let_me_know');
1171+
},5000);
1172+
1173+
// Cleanup listeners when this controller is destroyed
1174+
$scope.$on('$destroy', function handler() {
1175+
ObserverService.detachByEvent('let_me_know')
1176+
});
1177+
}
1178+
```
1179+
**Public Repository to get you started**
1180+
https://github.com/greglbd/angular-observer-pattern
1181+
11491182
## References
11501183
11511184
1. [Wikipedia](https://en.wikipedia.org/wiki). The source of all brief descriptions of the design patterns is wikipedia.

0 commit comments

Comments
 (0)