javascript - 使用 knockoutjs 调用 ajax 后,数据未按应有的方式绑定(bind)

标签 javascript jquery knockout.js

我有一个使用knockoutjs创建的网格,它一开始工作得很好,现在我使用window.location.hash来运行另一个查询,它也工作并且查询返回正确的结果数据量但是当我将其插入到 observableArray 中时(也能正确插入),网格不会更新数据并显示旧数据...我正在使用 在插入新数据集之前,也在observableArray上使用removeAll()函数,但它不会更新我的网格,我怀疑DOM有问题? 我应该提到,当我重新加载页面时(因为页面的 url 保留了查询的哈希值),我的网格显示了数据并且工作完美。由于某种原因它需要重新加载页面并且没有它就无法工作,

这是我的 JS:

if (!ilia) var ilia = {};

ilia.models = function () {
    var self = this;
    this.pageCount = ko.observable(0);

    //this is the observableArray that i am talking about ++++++++
    this.items = ko.observableArray();
    var $pagination = null;
    var paginationConfig = {
        startPage: 1,
        totalPages: 20,
        onPageClick: function (evt, page) {
            self.generateHash({ pageNum: page });
            self.getData();
        }
    }
    var hashDefault = {
        pageNum: 1,
        pageSize: 20,
        catId: null,
        search: ""
    }
    this.dataModel = function (_id, _name, _desc, _thumb, _ext) {
        var that = this;
        this.Id = ko.observable(_id);
        this.Name = ko.observable(_name);
        this.Desc = ko.observable(_desc);
        this.Url = '/site/ModelDetail?id=' + _id;

        var b64 = "data:image/" + _ext + ";base64, ";
        this.thumb = ko.observable(b64 + _thumb);
    }
    this.generateHash = function (opt) {
        //debugger;
        var props = $.extend(hashDefault, opt);
        var jso = JSON.stringify(props);
        var hash = window.location.hash;
        var newHash = window.location.href.replace(hash, "") + "#" + jso;
        window.location.href = newHash;
        return jso;
    }

    this.parseHash = function () {

        var hash = window.location.hash.replace("#", "");
        var data = JSON.parse(hash);
        if (data)
            data = $.extend(hashDefault, data);
        else
            data = hashDefault;
        return data;
    }

    var _cntrl = function () {
        var _hdnCatName = null;
        this.hdnCatName = function () {
            if (_hdnCatName == null)
                _hdnCatName = $("hdnCatName");
            return _hdnCatName();
        };

        var _grid = null;
        this.grid = function () {
            if (_grid == null || !_grid)
                _grid = $("#grid");
            return _grid;
        }

        this.rowTemplate = function () {
            return $($("#rowTemplate").html());
        }
    }
    this.createPagnation = function (pageCount, pageNum) {
        $pagination = $('#pagination-models');
        if ($pagination && $pagination.length > 0)
            if (paginationConfig.totalPages == pageCount) return;

        var currentPage = $pagination.twbsPagination('getCurrentPage');
        var opts = $.extend(paginationConfig, {
            startPage: pageNum > pageCount ? pageCount : pageNum,
            totalPages: pageCount,
            onPageClick: self.pageChange
        });

        $pagination.twbsPagination('destroy');
        $pagination.twbsPagination(opts);
    }
    this.pageChange = function (evt, page) {
        var hash = self.parseHash();
        if (hash.pageNum != page) {
            self.generateHash({ pageNum: page });
            self.getData();
        }
    }

    this.getData = function () {
        var _hash = self.parseHash();
        inputObj = {
            pageNum: _hash.pageNum,
            pageSize: _hash.pageSize,
            categoryId: _hash.catId
        }
        //debugger;
        //console.log(_hash);

        if (inputObj.categoryId == null) {
            ilia.business.models.getAll(inputObj, function (d) {
                //debugger;
                if (d && d.IsSuccessfull) {
                    self.pageCount(d.PageCount);
                    self.items.removeAll();
                    _.each(d.Result, function (item) {
                        self.items.push(new self.dataModel(item.ID, item.Name, item.Description, item.Thumb, item.Extention));
                    });

                    if (self.pageCount() > 0)
                        self.createPagnation(self.pageCount(), inputObj.pageNum);
                }
            });
        }
        else {
            ilia.business.models.getAllByCatId(inputObj, function (d) {
                if (d && d.IsSuccessfull) {
                    self.pageCount(d.PageCount);
                    self.items.removeAll();
                    console.log(self.items());
                    _.each(d.Result, function (item) {
                        self.items.push(new self.dataModel(item.ID, item.Name, item.Description, item.Thumb, item.Extention));
                    });
                    // initializing the paginator
                    if (self.pageCount() > 0)
                        self.createPagnation(self.pageCount(), inputObj.pageNum);
                    //console.log(d.Result); 
                }
            });
        }


    }
    this.cntrl = new _cntrl();

};

并初始化:

ilia.models.inst = new ilia.models();

$(document).ready(function () {

    if (!window.location.hash) {
        ilia.models.inst.generateHash();
        $(window).on('hashchange', function () {
            ilia.models.inst.getData();
        });

    }
    else {
        var obj = ilia.models.inst.parseHash();
        ilia.models.inst.generateHash(obj);
        $(window).on('hashchange', function () {
            ilia.models.inst.getData();
        });

    }

    ko.applyBindings(ilia.models.inst, document.getElementById("grid_area"));
    //ilia.models.inst.getData();
});

最佳答案

在此处查看 HTML 绑定(bind)也许也很有用。 是否有任何控制台错误?您确定由于某些服务器端缓存等原因收到的新数据不是旧数据吗?

无论如何,如果不是其中任何一个:

您正在使用 deferred updates ?如果数组大小没有改变,我已经看到 KO 无法跟踪嵌套 View 模型的属性,这意味着如果数组大小没有改变,那么它很可能会忽略通知订阅者。你可以用以下方法解决这个问题

self.items.removeAll();
ko.tasks.runEarly();
//here's the loop

如果上面的解决方案不起作用,也许 observable.valueHasMutated() 有用吗? https://forums.asp.net/t/2056128.aspx?What+is+the+use+of+valueHasMutated+in+Knockout+js

关于javascript - 使用 knockoutjs 调用 ajax 后,数据未按应有的方式绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44885221/

相关文章:

javascript - 将 XML feed 转换为 JSON,保留 itunes :image data

javascript - FancyBox - "Don' t 再次显示此消息“按钮?

javascript - 如何停止选择框以使用 select2 插件

javascript - KnockoutJS 每个文档绑定(bind)多次

knockout.js - knockout 2 级数组中的多个 foreach

Javascript 数学显示错误的数字

javascript - Jquery:获取 CSS 或样式

javascript - 为什么 AngularJS 在每个摘要循环上执行函数?

JQuery 图像 Accordion 事件 CSS

javascript - 删除函数中的数据绑定(bind)