Jude Fisher
Jude Fisher

Reputation: 11294

Is there any kind of wildcard operator in the Durandal observable plugin, to subscribe to a change in any property?

Is there any kind of wildcard operator in the Durandal observable plugin, as there is in (for example) JsObservable?

The Durandal observable documentation gives this example:

var observable = require('plugins/observable');

var viewModel:{
    firstName:'',
    lastName:''
};

observable(viewModel, 'firstName').subscribe(function(value){
    console.log('First name changed.');
});

viewModel.firstName = 'Test';

What I'd like to do is use a wildcard to subscribe to any changed property on the target. Something like this:

observable(viewModel, '*').subscribe(function(property, value){
        console.log(property + ' changed.');
    });

I don't see anything in the API documentation, but wondered if there was anything undocumented, or if anyone has a workaround to implement this behaviour.

Upvotes: 1

Views: 83

Answers (2)

Jude Fisher
Jude Fisher

Reputation: 11294

With thanks to U10 for the start above, (and with reference to a few examples on the web) I came up with the following, which uses a closure to track all the necessary properties. It's a bit messy but it does what I need for now - hopefully it will be of use to someone.

var ChangeTracker = (function () {
        function ChangeTracker() {
        }
        ChangeTracker.prototype._trackChange = function (prop, target) {
            var type = typeof (target[prop]);
            var value = target[prop];
            _logger.log("_trackChange", { target: target, prop: prop, type: type, value: value }, "CT");
            _obs(target, prop).subscribe(function (newValue) {
                var obj = {
                    target: target,
                    prop: prop,
                    newValue: newValue,
                    oldValue: value
                };
                _logger.log(">>>>>>>>>>>>>>> CHANGE!", obj, "CT");
                value = newValue;
            });
        };

        ChangeTracker.prototype.TrackChanges = function (target) {
            var _this = this;
            for (var prop in target) {
                if (target.hasOwnProperty(prop)) {
                    this._trackChange(prop, target);
                }
                var underlying = ko.utils.unwrapObservable(target[prop]);
                if (underlying instanceof Array) {
                    ko.utils.arrayForEach(underlying, function (item) {
                        _this.TrackChanges(item);
                    });
                } else if (typeof underlying === "object") {
                    this.TrackChanges(underlying);
                }                
            }
            }
        };
        return ChangeTracker;
    })();

Upvotes: 0

Dmitry Zaets
Dmitry Zaets

Reputation: 3277

Unfortunately, there is no wildcard operator for this functionality.

But you can easily create wrapper module for this functionality.

Here is small example:

var observable = require('plugins/observable');

var wildcardObservable = function(obj, changeCallback){
  for(var prop in obj){
    observable(obj, prop).subscribe(changeCallback);
  }
}

var changeCallback = function() {
  console.log('property changed.');
  }

Usage:

  var viewModel:{
    firstName:'',
    lastName:''
  };

wildcardObservable(viewModel, changeCallback);

Upvotes: 1

Related Questions