Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout using $data for component parameter within a foreach

I'am starting to play with component but i'am struggling with this simple code.

When I put a breakpoint in the function viewModel(params), the object params.data is my view model viewModelHelloWorld whereas I expected it to be an item of my array. What am I doing wrong ?

Html:

<body>
    Hello <span data-bind="text:name"></span>

    <table data-bind="foreach: arrays">
        <test-component params="data: $data"></test-component>
    </table>    

    <script type="text/html" id="line-items">
        <tr>
             <td data-bind="text: Key"></td>
        </tr>
    </script>

    <script type="text/javascript" src="knockout-3.4.0.js"></script>
    <script type="text/javascript" src="presentation_knockout.js"></script>
</body>

javascript

(function() {
    function viewModelHelloWorld()
    {
        var self = this;
        self.name = ko.observable("foo");       
        self.arrays = [ {Key:"1"}, {Key:"2"} ];
    }

    function viewModel(params)
    {
        var self = this;
        self.Key = ko.observable(params.data.Key);
    }

    ko.components.register('test-component', {
        viewModel: viewModel,
        template: { element: 'line-items' }
    });

    ko.applyBindings(new viewModelHelloWorld());
}());
like image 444
Marien Avatar asked Dec 11 '25 00:12

Marien


1 Answers

I didn't realize you were using the custom tag within a <table> element. Apparently the browser is pushing it out since it's not a valid child. The browser is effectively doing this:

<test-component params="data: $data"></test-component>
<table data-bind="foreach: arrays">
</table>

You would have to make sure you insert valid tags. Might as well do this instead:

<table data-bind="foreach: arrays">
    <tr data-bind="component: { name: 'test-component', params: $data }"></tr>
</table>

<script type="text/html" id="line-items">
    <td data-bind="text: Key"></td>
</script>

With your component:

ko.components.register('test-component', {
    template: { element: 'line-items' },
    viewModel: function viewModel(params) {
        this.Key = ko.observable(params.Key);
    }
});

You'll still be able to add more columns for each row in your component. Or better yet, make the entire table a component and build your view that way. That would make the most sense.

We came across this before in a similar situation here.

like image 113
Jeff Mercado Avatar answered Dec 12 '25 14:12

Jeff Mercado