Pausing notifications in KnockoutJS

http://www.knockmeout.net/2011/04/pausing-notifications-in-knockoutjs.html

by ernestohs

HTML

<script src="http://rniemeyer.github.com/KnockMeOut/Scripts/jquery.tmpl.js"></script>
<script src="http://rniemeyer.github.com/KnockMeOut/Scripts/knockout-latest.debug.js"></script>
<button data-bind="click: applyUpdates">Update users</button>
<hr/>
<table>
    <tr>
        <th>All Users</th>
        <th>
            Active users <br />
            Re-eval count: <span data-bind="text: activeUsersReevaluatedCount"></span>
        </th>
        <th>
            Active users w/pause <br />
            Re-eval count: <span data-bind="text: activeUsersWithPause.reevaluatedCount"></span>
        </th>
    </tr>
    <tr>
        <td data-bind="template: { name: 'usersTmpl', foreach: users }"></td>
        <td data-bind="template: { name: 'usersTmpl', foreach: activeUsers }"></td>
        <td data-bind="template: { name: 'usersTmpl', foreach: activeUsersWithPause }"></td>
    </tr>
</table>

<script id="usersTmpl" type="text/html">
    <div data-bind="text: name, css: { active: isActive }"></div>
</script>

<hr/>

CSS

td, th { vertical-align: top; border: solid black 1px; padding: 2px; }
.active { color: green; }

JavaScript

function User(id, name) {
    this.id = ko.observable(id);
    this.name = ko.observable(name);
    this.isActive = ko.observable(false);
}

var viewModel = {
    users: ko.observableArray([
        new User(1, "Bob"),
        new User(2, "Ted"),
        new User(3, "Joan"),
        new User(4, "Rod"),
        new User(5, "Rachel"),
        new User(6, "Greg"),
        new User(7, "Tim"),
        new User(8, "Polly"),
        new User(9, "Paul"),
        new User(10, "Sally"),
        new User(11, "Doug"),
        new User(12, "Cheryl"),
        new User(13, "Olivia"),
        new User(14, "Brent"),
        new User(15, "Todd"),
        new User(16, "Eve"),
        new User(17, "Henry"),
        new User(18, "Zach"),
        new User(19, "Brian"),
        new User(20, "Shirley"),
        new User(21, "Allen"),
        new User(22, "Anthony"),
        new User(23, "Wayne"),
        new User(24, "Brianna"),
        new User(25, "Randy")
        ]),
    applyUpdates: function() {
        this.activeUsersWithPause.pause();
        ko.utils.arrayForEach(this.users(), function(user) {
            var num = Math.floor(Math.random() * 2);
            user.isActive(num > 0);  //could check current status first here, before setting
        });
        this.activeUsersWithPause.resume();
    }
};

//wrapper for a dependentObservable that can pause its subscriptions/notifications
ko.pauseableDependentObservable = function(evaluatorFunction, evaluatorFunctionTarget) {
    var _cachedValue = "";
    var _isPaused = ko.observable(false);

    var result = ko.dependentObservable(function() {
        if (!_isPaused()) {
            return evaluatorFunction.call(evaluatorFunctionTarget);
        }
        return _cachedValue;
    }, evaluatorFunctionTarget);

    //for debug purposes
    result.reevaluatedCount = ko.observable(0);
    result.subscribe(function() {
        this.reevaluatedCount(this.reevaluatedCount() + 1);
    }, result);

    result.pause = function() {
       ...