17 April 2014

Using property getter/setter functions in Angular binding

OK, is most circumstances there's a better way to do this, but sometimes life would be easier if we could have a getter function and a setter function in an Angular binding.

Here's a helper function to make it more convenient to wrap them up. It's a bit rough, but does the job.


/**
 * For use when you really want to intercept two-way Angular bindings.
 * (And usually there's another better way)
 *
 * Example
 * <input
 *     ng-model="asProp(getCheckbox, setCheckbox, someArg1, someArg2).value"
 *     type="checkbox" />
 * ...
 * $scope.asProp = lib.asProp;
 * $scope.getCheckbox = function(someArg1, someArg2) { return ... };
 * $scope.setCheckbox = function(newValue, someArg1, someArg2) { ... };
 *
 * Takes a getter and a setter function.
 * And optionally additional arguments.
 * Returns an object with a single property called 'value'.
 * 'value' uses the provided getter and setter functions.
 * Additional arguments are passed to the getter and setter:
 * getter(additionalArgs) -> currentValue
 * setter(newValue, additionalArgs)
 */
lib.asProp = function (getter, setter /* .. args */) {
 var res = {};
 var args = _.toArray(arguments).slice(2);
 Object.defineProperty(res, 'value', {
  get: function () {
   return getter.apply(null, args);
  },
  set: function (val) {
   var args2 = [val].concat(args);
   setter.apply(null, args2);
  },
  enumerable: true,
  configurable: true
 });
 return res;
};