UNPKG

solidstate

Version:

An observable REST client for Javascript with a dramatically simple & fluent API.

79 lines (64 loc) 2.55 kB
if (typeof define !== 'function') { var define = require('amdefine')(module); } define([ 'knockout', 'underscore', 'URIjs', 'when', 'zoetropic' ], function(ko, _, URI, when, z) { 'use strict'; /** @class Attributes @classdesc An observable dictionary with the property that writing the whole dictionary actually writes individually to each attribute. */ var o = ko.observable, u = ko.utils.unwrapObservable, c = ko.computed, w = function(v) { return ko.isObservable(v) ? v : o(v); }; /** @callback Attributes~makeAttribute @param {String} key @param value @returns {Observable} @desc When a new attribute is added to the dictionary, this callback constructs the observable from the key and the value. By default, it uses ko.observable(value). */ /** Foo bar baz @param {{attributes: Object, ?makeAttribute: Attributes~makeAttribute}} args Named arguments to the constructor. */ var Attributes = function(args) { args = args || {}; var makeAttribute = args.makeAttribute || function(key, value) { return ko.observable(value); }; var actualAttributes = o({}); var wrappedAttributes = c({ read: function() { return actualAttributes(); }, write: function(_newAttributes) { var keysChanged = false; var nextAttributes = _(actualAttributes.peek()).clone(); var newAttributes = _newAttributes.peek ? _newAttributes.peek() : _newAttributes; _(newAttributes).each(function(value, key) { value = (value && value.peek) ? value.peek() : value; if (_(nextAttributes).has(key)) { nextAttributes[key](value); } else { nextAttributes[key] = makeAttribute(key, value); keysChanged = true; } }); // Note that there is currently no way to remove an attribute (because that is a weird thing to do and the semantics aren't clean) if (keysChanged) actualAttributes(nextAttributes); } }); if ( args.attributes ) { wrappedAttributes( args.attributes ); } return wrappedAttributes; }; return Attributes; });