Knockout check for nested view model

I want to use a combination of Libarary KnockoutJS, Knockout.Mapping plugin and Knockout-Validation plugin to display some data that the user can manipulate.

My data comes as a nested object from an AJAX call, and I run that data through a mapping plugin to create a knockout view model by setting up validation rules with a mapping options object in ko.mapping.fromJS.

I was able to get the objects at the first level (name in the script below) to show a message if the field is empty, however, objects that are nested (IntroData.PlanName) do not display the validation message. Do I need to configure the mapping object differently for these nested objects?

ViewModel (example of what goes into my AJAX call):

var stuff = {
    IntroData: {
        PlanName: 'Test'
    },
    name: 'tes2s3t'
};

      

Mapping:

var validationMapping = {
    IntroData: {
        PlanName: {
            create: function (options) {
                return ko.observable(options.data).extend({
                    required: true
                });
            }
        }
    },
    name: {
        create: function (options) {
            return ko.observable(options.data).extend({
                required: true
            });
        }
    }
};

      

Supply:

ko.validation.init({
    registerExtenders: true,
    messagesOnModified: true,
    insertMessages: true,
    parseInputAttributes: true,
    messageTemplate: null,
    grouping: {
        deep: true
    }
}, true);

window.viewModel = ko.validatedObservable(ko.mapping.fromJS(stuff, validationMapping));

ko.applyBindings(window.viewModel);

      

Fiddle: http://jsfiddle.net/odxv53g9/5/

Thank!

+3


source to share


1 answer


The documentation for this is not clear, but it seems to ko.mapping.fromJS()

ignore nested mappings, so the "create" method for PlanName is never called.

Instead of IntroData, you can add an explicit mapping:



IntroData: {
    create: function (options) {
        var nestedMapping = {
            PlanName: {
                create: function (options) {
                    return ko.observable(options.data).extend({
                        required: true
                    });
                }
            }
        }

        return ko.mapping.fromJS(options.data, nestedMapping);
    }        
}

      

Here is a working fiddle: http://jsfiddle.net/odxv53g9/6/

0


source







All Articles