AngularJS: 2-way binding of custom string serialization

Short Question:

How to create a <input type="text"> which contains a custom-format string serialization of an object in a way that editing the string updates the model and vice versa?

I think AngularJS’ directives are the way to go, but i can’t get it pinned down.

Long Question:

Prequel

I have a object which is my application’s “master model”. it can be serialized to a string of a specific format:

  1. it has 2-3 attributes, whose serializations are joined by “;” (no trailing “;” if the third is missing)

  2. attributes 2 and 3 are lists of objects, and serialized by joining those with “,”.

  3. the serialization of the objects is just one of their string attributes, or two ow them with “x” between.

so i have a constructor (accepting a spec string), and a toString function. Following; the latter for clarity:

World.prototype.toString = function() {
    var spec = [];

    spec[0] = this.version;
    spec[1] = this.layers.map(function(layer) {
        var c = (layer.c > 1) ? layer.c + 'x' : '';
        return c + layer.id; //e.g. 'T' or '2xT'
    }).join(',');

    //spec[2] in python: ','.join(option.id for option in options if option.checked)

    var options = this.options.filter(function(option) {
        return option.checked;
    });
    if (options.length > 0)
        spec[2] = options.map(function(option) {
            return option.id;
        }).join(',');

    return spec.join(';');
};

The directive i tried to use looks thusly, but the $watch only fires once.

angular.module('layersApp', []).directive('spec', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            scope.$watch('world', function(val) {
                element.val(val.toString());
                console.log('object updated', element.val());
            }, true);
            element.blur(function(e) {
                scope.world = new World(element.val());
            });
        }
    };
});

Actual long question

What i want is an easy way to make this work,

<input type="text" data-ng-model="theWorld" spec>

where spec is the custom directive shown above, setting up the two-way binding

Outlook

it would be awesome if this could result in a generic “serialization” directive used like that:

<input type="text" data-serialization="string2Foo, foo2String" data-ng-model="foo">

Which would look up the object foo, and the functions string2Foo and foo2String to setup custom (de)serialization.

I think you can use of $parsers and $filters of ngModel controller. Here is the simplest example of doing it. http://plnkr.co/edit/13PJN2

It should be easy to add validation, too.

I tried to make it accept custom serializer from parent scope, but failed to do so. Not sure about it.