Joseph Sjoblom
Joseph Sjoblom

Reputation: 171

How to get children count and display message using Knockout observable array

I'm trying to make a dynamic prototype to load json and display on page with paging.

I'm having issues displaying children from an observable array. I'm trying to get the children text and total count of messages present.

When you click through using the next button, the first child object is showing, but I'm getting an error that 'item' isn't define, but I'm not sure why.

http://jsfiddle.net/mujaji/bpdw2vcb/2/

Javascript:

(function() {
'use strict';
ko.extenders.paging = function(target, pageSize) {
    var _pageSize = ko.observable(pageSize || 10),
        // default pageSize to 10
        _currentPage = ko.observable(1); // default current page to 1
    target.pageSize = ko.computed({
        read: _pageSize,
        write: function(newValue) {
            if (newValue > 0) {
                _pageSize(newValue);
            }
            else {
                _pageSize(10);
            }
        }
    });

    target.currentPage = ko.computed({
        read: _currentPage,
        write: function(newValue) {
            if (newValue > target.pageCount()) {
                _currentPage(target.pageCount());
            }
            else if (newValue <= 0) {
                _currentPage(1);
            }
            else {
                _currentPage(newValue);
            }
        }
    });

    target.pageCount = ko.computed(function() {
        return Math.ceil(target().length / target.pageSize()) || 1;
    });

    target.currentPageData = ko.computed(function() {
        var pageSize = _pageSize(),
            pageIndex = _currentPage(),
            startIndex = pageSize * (pageIndex - 1),
            endIndex = pageSize * pageIndex;

        return target().slice(startIndex, endIndex);
    });

    target.moveFirst = function() {
        target.currentPage(1);
    };
    target.movePrevious = function() {
        target.currentPage(target.currentPage() - 1);
    };
    target.moveNext = function() {
        target.currentPage(target.currentPage() + 1);
    };
    target.moveLast = function() {
        target.currentPage(target.pageCount());
    };

     target.getValueCount = function() {
            target.messages.value().length;
    };

    return target;
};
}());
/// -- End paging extender -- \\\

/// Sample View Model that has an observableArray extended with the paging extender
var ViewModel = function() {
var self = this;
self.items = ko.observableArray([
{value: '1', messages: []},
{value: '2', messages: [{value: 'some text', critical: true}, {value: 'some more text', critical: false}, {value: 'even more text', critical: false}]},
{value: '3', messages: []},
{value: '4', messages: []},
{value: '5', messages: [{value: 'some text', critical: true}]},
{value: '6', messages: []},
{value: '7', messages: []},
{value: '8', messages: []},
{value: '9', messages: []},
{value: '10', messages: []},
{value: '11', messages: []},
{value: '12', messages: []},
{value: '13', messages: []}]).extend({
    paging: 1
});
};


ko.applyBindings(new ViewModel());

HTML:

<div style="float:left; border: 1px solid black;">
Paged Array
<ul data-bind="foreach : items.currentPageData">
    <li data-bind="text: value"></li>
    <li data-bind="foreach: messages">
      <span data-bind="text: value"></span>
      <span data-bind="text: items.getValueCount"></span>
      <span data-bind="if: critical">
        <i class="fa fa-exclamation-triangle">!</i>
      </span>
    </li>
</ul>
</div>

Can someone show me what I'm doing wrong?

thanks Joe

Upvotes: 1

Views: 590

Answers (1)

gh9
gh9

Reputation: 10703

You are on the right path that all observables are functions (in knockout.js)

once you enter a foreach loop

<ul data-bind="foreach : items.currentPageData">

Knockout will 'unpack' (that is not the correct terminology) the function for you, and leave you with access to the raw value.

when you do value().length you are trying to access the value as if it were a function. At this point in time it is no longer a function but the value that the function wrapped.

So to fix the issue, just remove the (), making it look like value.length.

Upvotes: 1

Related Questions