Search code examples
javascriptdata-bindingnativescript

Nativescript UI-Builder and Databinding


I try to build a custom component consisting of multiple TextFields. This component should use twoWay databinding via Observable internally. But I am simply not able to get it working.

main.js

exports.loaded = function(args){
    var page = args.object;
    page.bindingContext = model;

    var outerContainer = page.getViewById('outerContainer');

    model.vma = new Observable({
        label: "NiceLabel"
    });
    var vma = durationRow.init({
        model: model.vma
    });

    outerContainer.addChild(vma);
};

widget / durationrow.js

exports.init = function(options){
    model = _.isUndefined( options )
        ? model
        : options.model;

    _.defaults(model, {
        label:      "no data given",
        start:      "",
        end:        "",
        duration:   "30"
    });

    var durationRow = builder.load({
        path: 'widgets/durationRow',
        name: 'durationRow',
    });

    durationRow.getViewById("startText").bind({ 
        sourceProperty: "start", 
        targetProperty: "text", 
        twoWay: true }, 
    model);

    return durationRow;
}

The data originally in the start, end, duration fields get inserted into the text properties of my XML-layouted view. But changes on the model don't get propagated into the UI after the initial "render".

I tried XML-based databinding via text={{ start }} in my XML and this JS-based data binding. Both only works in "initial render" no updates get promoted.

Any suggestions? Thanks!


Solution

  • Ok, I got some things wrong. I built the whole init thing because I wasn't able to get "data" to my "widget". After all it all happens based on a simple small error... I tried to use bindContext instead of bindingContext and all hell...

    So the working solution:

    main.js

    var row = builder.load({
        path: 'widgets/durationRow',
        name: 'durationRow',
        attributes: {
            bindingContext: rowData
        }
    });
    

    And now nothing else is needed in durationRow.js. All JS-access to rowData is done via bindingContext and everything works like a charm :)