PGallagher
PGallagher

Reputation: 3113

Knockout.js Dynamic HTML Binding returning [object Object]

I'm just starting out with Knockout.js, and I've got a query about dynamic HTML.

I'm creating a dynamic Questionnaire. This has;

I've mapped my options using the $.map function, like;

this.options = $.map(questionOptions, function(text) { 
                                                       return new Option(text) 
                                                     });

I'm generating some html dynamically in the ViewModel, however when I try and concatenate say the Option Text into something like a set of Radio Buttons;

var htmlContent = '';
ko.utils.arrayForEach(_self.options, function (item) {
    htmlContent += '<input type="radio" name="' + ko.utils.unwrapObservable(_self.questionNumber) + '" data-bind="attr: {value: value}, checked: $root.selected" />\r\n';
    htmlContent += '<span>\r\n';
    htmlContent += item.optionText;
    //htmlContent += ko.utils.unwrapObservable(item.optionText); // Doesn't Work
    //htmlContent += item.optionText(); // Doesn't Work
    htmlContent += '</span>\r\n';
                });

return htmlContent;

I end up with a bunch of;

[object Object]

I've tried a couple of alternatives and gotten a bit stuck with where to go..

I'm not sure how to use Templates, as I'm planning on having Text Boxes, Radio Buttons, Drops Downs, Lists, etc all together. But maybe my knowledge is just lacking here!?

Here's a jsFiddle with some example code;

http://jsfiddle.net/PGallagher69/wA6mQ/21/

Any ideas?

Upvotes: 0

Views: 2011

Answers (1)

haim770
haim770

Reputation: 49133

Your optionText is indeed an Option object.

Try:

htmlContent += item.optionText.optionText;

UPDATE:

The real problem lies here:

function PagesViewModel(pageNo, pageHeader, questions) {
    this.pageNumber = ko.observable(pageNo);
    this.pageHeaderText = ko.observable(pageHeader);

    this.questionItems = ko.observableArray($.map(questions, function (n) {
        return [new QuestionViewModel(n.questionType, n.questionNumber, n.questionText, n.pointsBudget, n.options)]
    }));
}

When you're creating your PagesViewModel, the questions parameter is already an array of QuestionViewModel objects, and by assigning this.questionItems with your custom function, you're re-creating the QuestionViewModel, passing it n.options that is already an array of Option objects thus re-wrapping it again with an Option object, and that is why you're eventually gonna need item.optionText.optionText instead of simply item.optionText.

Try this:

function PagesViewModel(pageNo, pageHeader, questions) {
    this.pageNumber = ko.observable(pageNo);
    this.pageHeaderText = ko.observable(pageHeader);
    this.questionItems = ko.observable(questions);
}

Upvotes: 2

Related Questions