Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added Knockout example

  • Loading branch information...
commit b52c8d83cbc0801845f2b05934c2015914163b10 1 parent a9da878
@RoyJacobs authored
View
7 examples/knockout/package.json
@@ -0,0 +1,7 @@
+{
+ "name": "koExample",
+ "version": "1.0.0",
+ "dependencies": {
+ "express": "latest"
+ }
+}
View
41 examples/knockout/public/index.html
@@ -0,0 +1,41 @@
+<html>
+ <head>
+ <!--
+ All dependencies are loaded through RequireJS.
+ Because I don't want to include all dependencies in the example I configure RequireJS to download them from GitHub instead.
+ -->
+ <script type="text/javascript">
+ var require = {
+ paths: {
+ "ko": "http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.1.0",
+ "domReady": "https://raw.github.com/requirejs/domReady/latest/domReady",
+ "intravenous": "https://raw.github.com/RoyJacobs/intravenous/master/build/output/intravenous-latest"
+ }
+ };
+ </script>
+ <script type="text/javascript" src="http://requirejs.org/docs/release/2.0.0/minified/require.js" data-main="scripts/app"></script>
+ </head>
+ <body>
+ <div style="float:left; width: 60%">
+ <h1>Knockout sample</h1>
+ <p>
+ This sample illustrates how Intravenous can be used to help manage the lifetime of Knockout viewmodels.
+ </p>
+ <p>
+ Items: <span data-bind="text: itemCount"></span>
+ <button data-bind="click: addItem">Add item</button>
+ </p>
+ <!-- ko foreach: items -->
+ <p>
+ Item (ID: <span data-bind="text: myComputed"></span>) <button data-bind="click: $parent.removeItem">Remove</button>
+ </p>
+ <!-- /ko -->
+ </div>
+ <div style="float:right; width: 40%; background: #eee">
+ <h3>Application log</h3>
+ <!-- ko with: log -->
+ <pre data-bind="text: contents"></pre>
+ <!-- /ko -->
+ </div>
+ </body>
+</html>
View
19 examples/knockout/public/scripts/app.js
@@ -0,0 +1,19 @@
+define(["ko", "intravenous", "domReady", "log", "models/appModel", "models/itemModel", "models/subItemModel"], function(ko, intravenous, domReady, log, appModel, itemModel, subItemModel) {
+ domReady(function() {
+ // We configure the container in such a way that we call any "dispose" methods that may be present on our models.
+ var container = intravenous.create({
+ onDispose: function(instance, key) {
+ if (instance.dispose) instance.dispose();
+ }
+ });
+
+ // Register all the components of our application. Because "log" is a singleton, it will be reused among all components.
+ container.register("log", log, "singleton");
+ container.register("app", appModel);
+ container.register("item", itemModel);
+ container.register("subItem", subItemModel);
+
+ // Finally, we get the main model and use that as our main viewmodel.
+ ko.applyBindings(container.get("app"));
+ });
+});
View
25 examples/knockout/public/scripts/log.js
@@ -0,0 +1,25 @@
+define(["ko"], function(ko) {
+ var model = function() {
+ this.contents = ko.observable("");
+ this.add = function(text) {
+ var contents = this.contents();
+ if (contents) contents += "\n";
+
+ // Timestamp the incoming line
+ var pad = function(val) {
+ var s = val.toString();
+ return s.length < 2 ? "0" + s : s
+ }
+
+ var date = new Date();
+ var timestamp = pad(date.getUTCHours()) + ":" + pad(date.getUTCMinutes()) + ":" + pad(date.getUTCSeconds());
+ text = timestamp + " --> " + text;
+ contents += text;
+
+ this.contents(contents);
+ };
+
+ this.add("Log created");
+ };
+ return model;
+});
View
31 examples/knockout/public/scripts/models/appModel.js
@@ -0,0 +1,31 @@
+define(["ko"], function(ko) {
+ var model = function(log, itemFactory) {
+ var _this = this;
+
+ this.log = log;
+
+ // Here is some logic that allows the application to dynamically add and remove items.
+ this.itemFactory = itemFactory;
+ this.items = ko.observableArray();
+ this.itemCount = ko.computed(function() {
+ return this.items().length;
+ }, this);
+
+ this.addItem = function() {
+ this.items.push(this.itemFactory.get());
+ };
+
+ // When we remove an item we should also let the itemFactory know that it has been disposed.
+ // This will in turn release all of the item's dependencies.
+ this.removeItem = function() {
+ var item = this;
+ _this.items.remove(item);
+ _this.itemFactory.dispose(item);
+ };
+
+ this.log.add("appModel initialized");
+ };
+
+ model.$inject = ["log", "itemFactory"];
+ return model;
+});
View
33 examples/knockout/public/scripts/models/itemModel.js
@@ -0,0 +1,33 @@
+define(["ko"], function(ko) {
+ var itemId = 0;
+
+ var model = function(log, subItemFactory) {
+ var _this = this;
+
+ this.log = log;
+ this.id = ++itemId;
+
+ // We create subItem through its factory so we can pass in extra dependencies. In this case we simply pass in the ID of this item.
+ this.subItem = subItemFactory.use("item/id", this.id).get();
+
+ // The "isDisposed" observable will be set to true when the model is disposed.
+ // This can be used to automatically dispose all computed's the model may have, thereby releasing any subscriptions.
+ this.isDisposed = ko.observable(false);
+ this.myComputed = ko.computed(function() {
+ return this.id;
+ }, this, { disposeWhen: this.isDisposed });
+
+ // The "dispose" method will be invoked when the item is disposed from the itemFactory in appModel.
+ // Note: When we get here, subItem will already have been disposed automatically! You don't need to release any dependencies yourself.
+ this.dispose = function() {
+ // Setting the isDisposed to true to allow the computeds to release themselves.
+ this.isDisposed(true);
+ this.log.add("itemModel " + this.id + " disposed");
+ };
+
+ this.log.add("itemModel " + this.id + " initialized");
+ };
+
+ model.$inject = ["log", "subItemFactory"];
+ return model;
+});
View
15 examples/knockout/public/scripts/models/subItemModel.js
@@ -0,0 +1,15 @@
+define(["ko"], function(ko) {
+ var model = function(log, id) {
+ this.log = log;
+ this.id = id;
+
+ this.dispose = function() {
+ this.log.add("subItemModel for " + id + " disposed");
+ };
+
+ this.log.add("subItemModel for " + id + " initialized");
+ };
+
+ model.$inject = ["log", "item/id"];
+ return model;
+});
View
5 examples/knockout/readme.md
@@ -0,0 +1,5 @@
+### Knockout example
+A simple example which illustrates how you can use Intravenous to handle viewmodel lifetime with Knockout.
+
+1. `npm install`
+1. `node server`
View
12 examples/knockout/server.js
@@ -0,0 +1,12 @@
+var express = require('express'),
+ app = express.createServer();
+
+app.configure(function(){
+ app.use(express.methodOverride());
+ app.use(express.bodyParser());
+ app.use(app.router);
+ app.use(express.static(__dirname + '/public'));
+ app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
+});
+
+app.listen(3000);
Please sign in to comment.
Something went wrong with that request. Please try again.