0
votes

I am fairly new to Knockout and trying to get my head around observables and computed observables.

Updated: JS Fiddle: http://jsfiddle.net/tQ576/4/ with running but broken example. Label's should turn green when something is entered into the input box.

I have a model like this:

var json = {
    name: 'Testing',
    items: [{
        question: 'Question 1',
        answer: '',
        isrequired: true,
        isvisible: true,
        complexObject: {
            FirstName: '',
            LastName: '',
            Email: ''
        }
    }, {
        question: 'Question 2',
        answer: '',
        isrequired: true,
        isvisible: true,
        complexObject: {
            FirstName: '',
            LastName: '',
            Email: ''
        }
    }]
};

var ViewModel = function () {
    var self = this;
    self.profile = ko.observable(new Profile(json));
};

var Profile = function (init) {
    var self = this;
    self.name = ko.observable(init.name);
    self.items = ko.observableArray([]);
    for (var i = 0; i < init.items.length; i++) {
        self.items.push(new ProfileItem(init.items[i]));
    }
};

var ComplexObject = function () {
    var self = this;
    self.name = ko.observable("");
    self.email = ko.observable("");
}

var ProfileItem = function (item) {
    var self = this;
    self.question = ko.observable(item.question);
    self.answer = ko.observable(item.answer);
    self.complexObject = ko.observable(new ComplexObject());
    self.isvisible = ko.observable(item.isvisible);
    self.isrequired = item.isrequired;
    self.cssclasses = ko.computed(function () {
        if (self.complexObject().Email != undefined && self.complexObject().Email().length > 0) {
            return "satisfied";
        } else {
            return "required";
        }
    });
};

ko.applyBindings(new ViewModel());

then in my html I have templates like this:

<div data-bind="foreach: profile().items">
    <div data-bind="css: cssclasses">
        <span data-bind="text: question"></span><br />
        <div data-bind="with: complexObject">
            <input data-bind="value: email" />
        </div>
    </div>
</div>
<div data-bind="text: ko.toJSON($root)"></div>

It seems that when a value is updated for "Email" the cssclasses computed value never recomputes. Is there a way to force this recompute?

Best regards and thanks to everyone for the help.

JS Fiddle: http://jsfiddle.net/tQ576/4/

Hal

1
I think we also need to see the source for ComplexObject. - Michael Best
It appears that the input's $data object ( from the HTML above ) is a ProfileItem. That doesn't have an Email observable in the code above. - Robert Slaney

1 Answers

1
votes

If you uncapitalize email in your computed, it works. See fiddle

Change self.complexObject().Email !== undefined && self.complexObject().Email().length > 0) to self.complexObject().email !== undefined && self.complexObject().email().length > 0) - because that's how you have it in your view model and your data bindings.