Skip to content

Instantly share code, notes, and snippets.

@BruceHubbard
Created December 13, 2012 16:23
Show Gist options
  • Save BruceHubbard/4277604 to your computer and use it in GitHub Desktop.
Save BruceHubbard/4277604 to your computer and use it in GitHub Desktop.
Code for my knockout scoring example
var week = {
  updateGame: function(game) {
		var gameToUpdate = _.find(this.games, function(g) { return g.id === game.id; });

		if(gameToUpdate) {
			if(game.awayTeam) gameToUpdate.awayTeam.total(game.awayTeam.total);
			if(game.homeTeam) gameToUpdate.homeTeam.total(game.homeTeam.total);
		}
	},
	games: [
		{
			id: '20121401',
-  		awayTeam: {
-				name: 'Denver', 
-				total: ko.observable(26)
-			},
+			awayTeam: {	name: 'Denver',	total: ko.observable(0) },
-  		homeTeam: {
-				name: 'Oakland', 
-				total: ko.observable(13)
-			}
+			homeTeam: { name: 'Oakland', total: ko.observable(0) }
		},
		{
			id: '20121402',
-  		awayTeam: {
-				name: 'San Diego', 
-				total: ko.observable(34)
-			},
+      awayTeam: { name: 'San Diego', total: ko.observable(0) },
-    	homeTeam: {
-				name: 'Pittsburgh', 
-				total: ko.observable(24)
-			}
+			homeTeam: { name: 'Pittsburgh', total: ko.observable(0) }
-  	}
+  	},
+		{
+			id: '20121403',
+			awayTeam: { name: 'Baltimore', total: ko.observable(0) },
+			homeTeam: { name: 'Washington', total: ko.observable(0) }
+		},
+		{
+			id: '20121404',
+			awayTeam: { name: 'Dallas', total: ko.observable(0) },
+			homeTeam: { name: 'Cincinnati', total: ko.observable(0) }
+		},
+		{
+			id: '20121405',
+			awayTeam: { name: 'St. Louis', total: ko.observable(0) },
+			homeTeam: { name: 'Buffalo', total: ko.observable(0) }
+		},
+		{
+			id: '20121406',
+			awayTeam: { name: 'Philadelphia', total: ko.observable(0) },
+			homeTeam: { name: 'Tampa Bay', total: ko.observable(0) }
+		},
+		{
+			id: '20121407',
+			awayTeam: { name: 'Atlanta', total: ko.observable(0) },
+			homeTeam: { name: 'Carolina', total: ko.observable(0) }
+		}
	]
};


/*
	THIS IS HERE TO SIMULATE DATA COMING FROM THE SERVER
	whether it's from an ajax call, websockets, etc. it 
	doesn't matter.  The server will pass back an updated
	game object and we'll pass it into the updateGame 
	method of our model.
*/
var updateFreq = 2000;

function simulateScoring() {
	//every x seconds pull a random game and random team and increment their score by
	//a random amount
	var randomGame = week.games[_.random(week.games.length - 1)]
	var teams = [randomGame.awayTeam, randomGame.homeTeam];
	var randomTeam = teams[_.random(teams.length - 1)]
	var newScore = randomTeam.total() + _.random(7);

	week.updateGame({
		id: randomGame.id,
		awayTeam: {total: (randomTeam === randomGame.awayTeam) ? newScore : randomGame.awayTeam.total()},
		homeTeam: {total: (randomTeam === randomGame.homeTeam) ? newScore : randomGame.homeTeam.total()}
	});

	setTimeout(simulateScoring, updateFreq);
}

setTimeout(simulateScoring, updateFreq);

ko.bindingHandlers.flashOnUpdate = {
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        if(ko.utils.unwrapObservable(valueAccessor()) > 0) {
        	$(element).addClass('updated', function() {
        		$(element).removeClass('updated', 1000);        		
        	});
        }
    }
};

ko.applyBindings(week);
/* apply a natural box layout model to all elements */
* { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }

.game {
  display: inline-block;
	margin: 10px;
	border: 1px black solid;
}

.game header {
	background-color: #DEDEC6;
}

.team, .total { display: inline-block; }

.team { width: 100px; }

.total { 
	width: 40px; 
	font-weight: bold;
	text-align: center;
}

+.updated {
+	background-color: black;
+	color: white;
+}
<!DOCTYPE html>
<html>
<head>
  <title>Scores</title>
  <link rel="stylesheet" type="text/css" href="css/styles.css" media="all">
</head>
<body>

  <section class="scores" data-bind="foreach: games">
		<div class="game">
			<header>
				<div class="team"></div>
				<div class="total">Total</div>
			</header>
			<div class="score">
				<div class="team" data-bind="text: awayTeam.name"></div>
-  			<div class="total" data-bind="text: awayTeam.total"></div>
+  			<div class="total" data-bind="text: awayTeam.total, flashOnUpdate: awayTeam.total"></div>
			</div>
			<div class="score">
				<div class="team" data-bind="text: homeTeam.name"></div>
-  			<div class="total" data-bind="text: homeTeam.total"></div>
+  			<div class="total" data-bind="text: homeTeam.total, flashOnUpdate: homeTeam.total"></div>
			</div>
		</div>
	</section>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
+  <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>
  <script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.1.0.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.2/underscore-min.js"></script>
  <script src="js/app.js"></script>
</body>
</html>
var week = {
  updateGame: function(game) {
		var gameToUpdate = _.find(this.games, function(g) { return g.id === game.id; });

		if(gameToUpdate) {
			if(game.awayTeam) gameToUpdate.awayTeam.total(game.awayTeam.total);
			if(game.homeTeam) gameToUpdate.homeTeam.total(game.homeTeam.total);
		}
	},
	games: [
		{
			id: '20121401',
			awayTeam: {
				name: 'Denver', 
				total: ko.observable(26)
			},
			homeTeam: {
				name: 'Oakland', 
				total: ko.observable(13)
			}
		},
		{
			id: '20121402',
			awayTeam: {
				name: 'San Diego', 
				total: ko.observable(34)
			},
			homeTeam: {
				name: 'Pittsburgh', 
				total: ko.observable(24)
			}
		}
	]
};


/*
	THIS IS HERE TO SIMULATE DATA COMING FROM THE SERVER
	whether it's from an ajax call, websockets, etc. it 
	doesn't matter.  The server will pass back an updated
	game object and we'll pass it into the updateGame 
	method of our model.
*/
var updateFreq = 2000;

function simulateScoring() {
	//every x seconds pull a random game and random team and increment their score by
	//a random amount
	var randomGame = week.games[_.random(week.games.length - 1)]
	var teams = [randomGame.awayTeam, randomGame.homeTeam];
	var randomTeam = teams[_.random(teams.length - 1)]
	var newScore = randomTeam.total() + _.random(7);

	week.updateGame({
		id: randomGame.id,
		awayTeam: {total: (randomTeam === randomGame.awayTeam) ? newScore : randomGame.awayTeam.total()},
		homeTeam: {total: (randomTeam === randomGame.homeTeam) ? newScore : randomGame.homeTeam.total()}
	});

	setTimeout(simulateScoring, updateFreq);
}

setTimeout(simulateScoring, updateFreq);

+ko.bindingHandlers.flashOnUpdate = {
+    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
+        if(ko.utils.unwrapObservable(valueAccessor()) > 0) {
+        	$(element).addClass('updated', function() {
+        		$(element).removeClass('updated', 1000);        		
+        	});
+        }
+    }
+};

ko.applyBindings(week);
 
/* apply a natural box layout model to all elements */
* { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }

.game {
  display: inline-block;
	margin: 10px;
	border: 1px black solid;
}

.game header {
	background-color: #DEDEC6;
}

.team, .total { display: inline-block; }

.team { width: 100px; }

.total { 
	width: 40px; 
	font-weight: bold;
	text-align: center;
}
<!DOCTYPE html>
<html>
<head>
  <title>Scores</title>
  <link rel="stylesheet" type="text/css" href="css/styles.css" media="all">
</head>
<body>

  <section class="scores">
		<div class="game">
			<header>
				<div class="team"></div>
				<div class="total">Total</div>
			</header>
			<div class="score">
				<div class="team">Denver</div>
				<div class="total">26</div>
			</div>
			<div class="score">
				<div class="team">Oakland</div>
				<div class="total">13</div>
			</div>
		</div>
		<div class="game">
			<header>
				<div class="team"></div>
				<div class="total">Total</div>
			</header>
			<div class="score">
				<div class="team">San Diego</div>
				<div class="total">34</div>
			</div>
			<div class="score">
				<div class="team">Pittsburgh</div>
				<div class="total">24</div>
			</div>			
		</div>			
	</section>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
  <script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.1.0.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.2/underscore-min.js"></script>
  <script src="js/app.js"></script>
	
</body>
</html>
- week.games[0].awayTeam.total = 333;
+ week.games[0].awayTeam.total(333);
var week = {
  games: [
  	{
			id: '20121401',
			awayTeam: {
				name: 'Denver', 
-				total: 26
+  			total: ko.observable(26)
			},
			homeTeam: {
				name: 'Oakland', 
-				total: 13
+  			total: ko.observable(13)
			}
		},
		{
			id: '20121402',
			awayTeam: {
				name: 'San Diego', 
-				total: 34
+  			total: ko.observable(34)
			},
			homeTeam: {
				name: 'Pittsburgh', 
-				total: 24
+  			total: ko.observable(24)
			}
		}
	]
};

ko.applyBindings(week);
<!DOCTYPE html>
<html>
<head>
  <title>Scores</title>
  <link rel="stylesheet" type="text/css" href="css/styles.css" media="all">
</head>
<body>

+ <section class="scores" data-bind="foreach: games">
+		<div class="game">
+			<header>
+				<div class="team"></div>
+				<div class="total">Total</div>
+			</header>
+			<div class="score">
+				<div class="team" data-bind="text: awayTeam.name"></div>
+				<div class="total" data-bind="text: awayTeam.total"></div>
+			</div>
+			<div class="score">
+				<div class="team" data-bind="text: homeTeam.name"></div>
+				<div class="total" data-bind="text: homeTeam.total"></div>
+			</div>
+		</div>
+	</section>

-  <section class="scores">
-  	<div class="game">
-			<header>
-				<div class="team"></div>
-				<div class="total">Total</div>
-			</header>
-			<div class="score">
-				<div class="team">Denver</div>
-				<div class="total">26</div>
-			</div>
-			<div class="score">
-				<div class="team">Oakland</div>
-				<div class="total">13</div>
-			</div>
-		</div>
-		<div class="game">
-			<header>
-				<div class="team"></div>
-				<div class="total">Total</div>
-			</header>
-			<div class="score">
-				<div class="team">San Diego</div>
-				<div class="total">34</div>
-			</div>
-			<div class="score">
-				<div class="team">Pittsburgh</div>
-				<div class="total">24</div>
-			</div>			
-		</div>			
-	</section>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
  <script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.1.0.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.2/underscore-min.js"></script>
  <script src="js/app.js"></script>
	
</body>
</html>
var week = {
  games: [
		{
			id: '20121401',
			awayTeam: {
				name: 'Denver', 
				total: 26
			},
			homeTeam: {
				name: 'Oakland', 
				total: 13
			}
		},
		{
			id: '20121402',
			awayTeam: {
				name: 'San Diego', 
				total: 34
			},
			homeTeam: {
				name: 'Pittsburgh', 
				total: 24
			}
		}
	]
};

ko.applyBindings(week);
var week = {
+  updateGame: function(game) {
+  	var gameToUpdate = _.find(this.games, function(g) { return g.id === game.id; });
+
+		if(gameToUpdate) {
+			if(game.awayTeam) gameToUpdate.awayTeam.total(game.awayTeam.total);
+			if(game.homeTeam) gameToUpdate.homeTeam.total(game.homeTeam.total);
+		}
+	},
  games: [
  	{
			id: '20121401',
			awayTeam: {
				name: 'Denver', 
				total: ko.observable(26)
			},
			homeTeam: {
				name: 'Oakland', 
				total: ko.observable(13)
			}
		},
		{
			id: '20121402',
			awayTeam: {
				name: 'San Diego', 
				total: ko.observable(34)
			},
			homeTeam: {
				name: 'Pittsburgh', 
				total: ko.observable(24)
			}
		}
	]
};

+/*
+	THIS IS HERE TO SIMULATE DATA COMING FROM THE SERVER
+	whether it's from an ajax call, websockets, etc. it 
+	doesn't matter.  The server will pass back an updated
+	game object and we'll pass it into the updateGame 
+	method of our model.
+*/
+var updateFreq = 2000;
+
+function simulateScoring() {
+	//every x seconds pull a random game and random team and increment their score by
+	//a random amount
+	var randomGame = week.games[_.random(week.games.length - 1)]
+	var teams = [randomGame.awayTeam, randomGame.homeTeam];
+	var randomTeam = teams[_.random(teams.length - 1)]
+	var newScore = randomTeam.total() + _.random(7);
+
+	week.updateGame({
+		id: randomGame.id,
+		awayTeam: {total: (randomTeam === randomGame.awayTeam) ? newScore : randomGame.awayTeam.total()},
+		homeTeam: {total: (randomTeam === randomGame.homeTeam) ? newScore : randomGame.homeTeam.total()}
+	});
+
+	setTimeout(simulateScoring, updateFreq);
+}
+
+setTimeout(simulateScoring, updateFreq);

ko.applyBindings(week);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment