anuith
anuith

Reputation: 739

KnockoutJS with PagerJS stop working after data bound

I'm working on KnockoutJS with PagerJS plugin and found this problem. I don't know if it is related to PagerJS or not but here's the problem.

I use page binding of pager.js with sourceOnShow property and there are child page inside the source contents bound with an observable property of its parent's ViewModel.

When the observable property changes, the child tried to update new data. But after the first value is bound, it seems it was stopped working. I put some logs in between each steps and the result comes as follows:

The result of my sample code displays only the job_id, the rest displays blocks with empty bindings and the console logged only log1 and log2. No other errors logged. As if it stopped working after the first binding.

my code is, for example

the main page

<script src="/js/jobspage.js"></script>
<!-- some elements -->
<div data-bind="page: {
    id: 'somepage',
    title: 'Some Page',
    sourceOnShow: 'template/somepage',
    role: 'start'
}"></div>
<div data-bind="page: {
    id: 'jobs',
    title: 'Jobs',
    sourceOnShow: 'template/jobs',
    with: JobsPageVM
}"></div>
<div data-bind="page: {
    id: 'other',
    title: 'Other Page',
    sourceOnShow: 'template/otherpage'
}"></div>

the /template/jobs

<div class="jobs" id="main" role="main">
    <div class="job-list" data-bind="page: {role: 'start'}">
        <!-- ko foreach: jobitems -->
        <div data-bind="event: {click: item_clicked}">
            <!-- item description -->
            <!-- item_clicked will set the selectedItem (observable) property of JobsPageVM -->
        </div>
        <!-- /ko -->
    </div>
    <div class="job-info" data-bind="page: {id: 'jobinfo', with: selectedItem}">
        <!--ko text: console.log('log1')--><!--/ko-->
        <!-- some elements -->
        <!--ko text: console.log('log2')--><!--/ko-->
        Job ID : <span class="job-value" data-bind="text: job_id"></span>
        <!--ko text: console.log('log3')--><!--/ko-->
        Job Title : <span class="job-value" data-bind="text: job_title"></span>
        <!--ko text: console.log('log4')--><!--/ko-->
    </div>
</div>

the jobspage.js

var JobsPageVM = function () {
    var self = this;
    var dataitems = ko.observableArray();

    self.isLoading = ko.observable(true);
    self.searchTerm = ko.observable("");
    self.jobitems = ko.computed(function () {
        var search_input = self.searchTerm().toLowerCase();
        if (search_input === "") {
            return dataitems();
        } else {
            return ko.utils.arrayFilter(dataitems(), function (item) {
                var data = item.cust_first_name + item.cust_last_name;
                return data.search(new RegExp(search_input, "i")) >= 0;
            });
        }
    }, this);

    self.selectedItem = ko.observable();
    self.branchID = ko.observable(sample_branch_id);

    self.getJobList = function (status) {
        self.isLoading(true);
        if (typeof (status) === "undefined") {
            status = "all";
        }

        $.ajax({
            url: "/api/job/branch/" + self.branchID(),
            data: {
                jobstatus: status
            },
            success: function (data) {
                dataitems(data); // data is an array of object items contains `job_id`, `job_title`, and more
                self.isLoading(false);
            },
            error: function (x, s, e) {
                console.log(x, s, e);
                self.isLoading(false);
            }
        });
    };

    self.item_clicked = function (vm, e) {
        self.selectedItem(vm);
        pager.navigate('jobs/jobinfo');
    };

    self.getJobList();
};

*I don't know whether it against the rule or not. This question was asked before but didn't answered, so I deleted and re-asking here. Thanks to @Stijn and @KristianNissen for help refine my question.

Upvotes: 0

Views: 331

Answers (1)

anuith
anuith

Reputation: 739

I found a kind of workaround, or maybe the solution. But I didn't quite sure the cause of the problem.

Originally, I tried to bind the selectedItem to the page: {with: ...} binding which resulted the problem above. Now I changed the binding of selectedItem with the element itself instead of inside page: binding.

I changed from this :

<div class="job-info" data-bind="page: {id: 'jobinfo', with: selectedItem}">

To this :

<div class="job-info" data-bind="page: {id: 'jobinfo'}, with: selectedItem">

And it seems to work fine now.

Upvotes: 0

Related Questions