Skip to content

Instantly share code, notes, and snippets.

@Detoo
Forked from bennadel/watch-vs-watch-collection.htm
Last active August 29, 2015 14:01
Show Gist options
  • Save Detoo/c272cf29138196c31c73 to your computer and use it in GitHub Desktop.
Save Detoo/c272cf29138196c31c73 to your computer and use it in GitHub Desktop.
<!doctype html>
<html ng-app="Demo">
<head>
<meta charset="utf-8" />
<title>
Scope $watch() vs. $watchCollection() In AngularJS
</title>
<style type="text/css">
a[ ng-click ] {
cursor: pointer ;
text-decoration: underline ;
}
</style>
</head>
<body ng-controller="AppController">
<h1>
Scope $watch() vs. $watchCollection() In AngularJS
</h1>
<p>
<a ng-click="changeDeepValue()">Change Deep Value</a>
&mdash;
<a ng-click="changeShallowValue()">Change Shallow Value</a>
&mdash;
<a ng-click="replaceAnItem()">Replace an item</a>
&mdash;
<a ng-click="replaceAnItemWithSameContents()">Replace an item with same contents</a>
&mdash;
<a ng-click="rebuild()">Rebuild</a>
&mdash;
<a ng-click="clear()">Clear</a>
</p>
<h2>
$watchCollection( collectionArray ) Log
</h2>
<ul>
<li ng-repeat="item in watchCollectionLog">
{{ item }}
</li>
</ul>
<h2>
$watch( collectionArray ) Log
</h2>
<ul>
<li ng-repeat="item in watchLog">
{{ item }}
</li>
</ul>
<h2>
$watch( collectionArray, [ Equality = true ] ) Log
</h2>
<ul>
<li ng-repeat="item in watchEqualityLog">
{{ item }}
</li>
</ul>
<!-- Load scripts. -->
<script src="https://code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="https://code.angularjs.org/1.2.9/angular.min.js"></script>
<script type="text/javascript">
// Create an application module for our demo.
var app = angular.module( "Demo", [] );
// -------------------------------------------------- //
// -------------------------------------------------- //
// I control the root of the application.
app.controller(
"AppController",
function( $scope ) {
// These are the log item to render upon change.
$scope.watchCollectionLog = [];
$scope.watchLog = [];
$scope.watchEqualityLog = [];
// the array collectionArray being watched.
$scope.collectionArray = [
{
id: 1,
value: 0
}
];
// the array collectionArray being watched.
$scope.collectionMap = {
key1: {
id: 1,
value: 0
}
};
// Use the relatively new watchCollection().
$scope.$watchCollection(
"collectionArray",
function( newValue, oldValue ) {
addLogItem( $scope.watchCollectionLog );
}
);
// Use the old watch() with default object equality,
// which defaults to use object REFERENCE checks.
$scope.$watch(
"collectionArray",
function( newValue, oldValue ) {
addLogItem( $scope.watchLog );
}
);
// Use the old watch() method, but turn on deep object
// equality, which will compare the deep object tree
// for changes.
$scope.$watch(
"collectionArray",
function( newValue, oldValue ) {
addLogItem( $scope.watchEqualityLog );
},
true // Object equality (not just reference).
);
// ---
// PUBLIC METHODS.
// ---
// Change a deep value in an existing item on in the
// current collectionArray.
$scope.changeDeepValue = function() {
// Add new item to collectionArray.
$scope.collectionArray[ 0 ].value = now();
};
// Add a new item to the collectionArray, causing a change
// in the shallow topology of the collectionArray.
$scope.changeShallowValue = function() {
// Add new item to collectionArray.
$scope.collectionArray.push({
id: ( $scope.collectionArray.length + 1 ),
value: now()
});
};
// replace an item with another item with a new reference
$scope.replaceAnItem = function() {
// Add new item to collectionArray.
$scope.collectionArray[$scope.collectionArray.length-1] = {
id: ( $scope.collectionArray.length ),
value: now()
};
}
// replace an item with another item with exact same content but a new reference
$scope.replaceAnItemWithSameContents = function() {
// copy item
var newItem = {
id: $scope.collectionArray[0].id,
value: $scope.collectionArray[0].value
}
// Add new item to collectionArray.
$scope.collectionArray[0] = newItem;
}
// I clear the log items.
$scope.clear = function() {
$scope.watchCollectionLog = [];
$scope.watchLog = [];
$scope.watchEqualityLog = [];
};
// I rebuild the underlying collectionArray, completely
// changing the reference.
$scope.rebuild = function() {
$scope.collectionArray = [{
id: 1,
value: 0
}];
};
// ---
// PRIVATE METHODS.
// ---
// I add a log item to the beginning of the given log.
function addLogItem( log ) {
var logItem = (
"Executed: " + now() +
" ( length: " + $scope.collectionArray.length + " )"
);
log.splice( 0, 0, logItem );
}
// I return the current UTC milliseconds.
function now() {
return( ( new Date() ).getTime() );
}
}
);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment