Durandal可观察数组不更新

时间:2014-08-19 04:39:30

标签: javascript knockout.js knockout-2.0 durandal-2.0

我将Durandal Samples中的分页示例复制到我的代码中,我注意到该函数只被调用一次。更改observable上的值对item observable数组没有任何影响,也不会重新调用SimpleGrid。我做错了什么?

我的gridViewModel第一次没有被其中的任何数据调用,也不会再被调用。

非常感谢。

start.html

<html snipped>
<div data-bind='compose: gridViewModel'></div>

start.js

define(['durandal/system', 'plugins/http', 'durandal/app', './simpleGrid', 'knockout', 'moment'], function (system, http, app, SimpleGrid, ko, moment) {
    //Note: This module exports an object.
    //That means that every module that "requires" it will get the same object instance.
    //If you wish to be able to create multiple instances, instead export a function.
    //See the "welcome" module for an example of function export.
    var self = this;
    self.start_date = ko.observable("");
    self.end_date = ko.observable("");
    self.records_per_page = ko.observable("");
    self.records = ko.observableArray([]);
    self.pages = ko.observableArray([]);
    var initialData = [];


    self.getShippersData = function () {
        var that = this;
        var obj = {
            start_date: this.start_date(),
            end_date: this.end_date(),
            search_for: this.search_for(),
            records_per_page: this.records_per_page()
        };

        http.get('shippers.php/records', obj).then(function (response) {
            that.records(response.dbrecs);
            that.initialData = response.pages;
            that.pages(response.pages);

            console.log("updating pages");
        }, function (error) {
            console.log("Error State : Call to shippers.php Failed");
        });

    };

    self.search_for = ko.observable("").extend({ rateLimit: { timeout: 500, method: "notifyWhenChangesStop" } });
    search_for.subscribe(function (searchTerm) {
        //make use of searchTerm i.e. search_for variable to make ajax call.
        //Whenever you change value of search_for, this method will invoke
        //console.log("This is a proxy for an AJAX call");

        self.getShippersData();

    });

    console.log("This is after the shipper call");
    console.log(initialData);

    self.items = ko.observableArray(initialData);
    self.gridViewModel = new SimpleGrid({
        data: self.pages,
        pageSize: self.records_per_page
    });

    return {
        items: items,
        start_date: start_date,
        end_date: end_date,
        records_per_page: records_per_page,
        search_for: search_for,
        records: records,
        pages: pages,
        getShippersData: getShippersData,
        gridViewModel: gridViewModel,
        SimpleGrid: SimpleGrid,
        activate: function () {
            //the router's activator calls this function and waits for it to complete before proceeding
            var begin = moment().startOf('day').format('DD/MM/YYYY HH:mm:ss');
            var end = moment().endOf('day').format('DD/MM/YYYY HH:mm:ss');

            begin = "15/05/2014 00:00:00";
            end = "18/05/2014 00:00:00";

            this.start_date(begin);
            this.end_date(end);

            this.getShippersData();
        },
        select: function (item) {
            //the app model allows easy display of modal dialogs by passing a view model
            //views are usually located by convention, but you an specify it as well with viewUrl
        },
        /*
        canDeactivate: function () {
            //the router's activator calls this function to see if it can leave the screen
            //return app.showMessage('Are you sure you want to leave this page?', 'Navigate', ['Yes', 'No']);
        }
        */
    };
});

simpleGrid.js

define(['knockout'], function (ko) {
    var SimpleGrid = function (configuration) {
        console.log("I am in SimpleGrid");
        console.log(configuration);

        this.data = configuration.data;
        this.currentPageIndex = ko.observable(0);
        this.pageSize = configuration.pageSize || 5;

        this.itemsOnCurrentPage = ko.computed(function () {
            var startIndex = this.pageSize * this.currentPageIndex();
            return this.data.slice(startIndex, startIndex + this.pageSize);
        }, this);

        this.maxPageIndex = ko.computed(function () {
            return Math.ceil(ko.utils.unwrapObservable(this.data).length / this.pageSize) - 1;
        }, this);
    };

    return SimpleGrid;
});

simpleGrid.html

<div>
    <ul class="pagination">
        <!-- ko foreach: ko.utils.range(0, maxPageIndex) -->
        <li>
            <a href="#" data-bind="text: $data + 1, click: function () { $root.currentPageIndex($data); }"></a>
        </li>
        <!-- /ko -->
    </ul>
</div>

1 个答案:

答案 0 :(得分:0)

我认为您需要在对象返回时使用self.作为前缀。 像这样:

return {
    items: self.items,
    start_date: self.start_date,
    end_date: self.end_date,
    records_per_page: self.records_per_page,
    search_for: self.search_for,
    records: self.records,
    pages: self.pages,
    getShippersData: self.getShippersData,
    gridViewModel: self.gridViewModel

然后在您的激活功能中,请拨打self.functionName而不是this.。 我和你一样做并在我回来的对象中调用this.时遇到了类似的问题。