Knockout ViewModel绑定,observables为空

时间:2014-08-25 21:30:38

标签: jquery knockout.js faceted-search

我正在清理我的模型,使其更加清晰,并在重构过程中遇到问题。最初我使用全局变量"结果"其中包含我的API中解析的Json。我重构它实际设置模型属性。

但是,我现在遇到了一个问题,我的两个可观察属性在绑定时是空的。它可能很简单,但我不确定发生了什么。

我在这里使用从我的API调用返回的JSON对象设置我的模型属性。

function BindJsonToModel(data) {
    var results = $.parseJSON(data);

    model.resources(results.ResourceResults);
    model.createFacets(results.ResourceFacets);
}

我的ViewModel在这里:

function ViewModel() {
    var self = this;

    self.resources = ko.observable();
    self.facets = ko.observable();

    self.createFacets = function (resourceFacets) {

        var realModel = [];

        ko.utils.arrayForEach(resourceFacets, function (item) {
            realModel.push({ name: item, IsChecked: ko.observable(true) });
        });

        self.facets(realModel);
    }

    self.resourceRows = ko.computed(function () {
        var rows = [],
            rowIndex = 0,
            itemsPerRow = 2;

        var resourceList = self.resources();

        if (resourceList != null) {

            for (var index = 0; index < resourceList.length; index++) {
                if (!rows[rowIndex]) {
                    rows[rowIndex] = [];
                }

                rows[rowIndex].push(resourceList[index]);

                if (rows[rowIndex].length == itemsPerRow) {
                    rowIndex++;
                }
            }
        }

        return rows;
    });

    self.selectAll = ko.computed({
        read: function () {
            var firstUnchecked = ko.utils.arrayFirst(self.facets, function (item) {
                return item.IsChecked() == false;
            });
            return firstUnchecked == null;
        },
        write: function (value) {
            ko.utils.arrayForEach(self.facets, function (item) {
                item.IsChecked(value);
            });
        }
    });
};

var model = new ViewModel();

ko.applyBindings(model);

我还改变了我通过新建并应用绑定来生成ViewModel的方式。我试图遵循基于KO文档的标准,这些文档在他们的文档和教程之间似乎有点不清楚。

非常感谢任何帮助。

一些其他信息。当我调试此代码时,我发现resourceRows属性实际上按预期迭代self.resourcesself.resourcesself.facets都包含值。只有当我绑定他们时,他们才会回来。

我对资源的绑定是:

<div class="container main-content">
    <div class="row resource-list">
        <div class="col-sm-4 col-xs-0">
        </div>
        <div class="col-sm-8 col-xs-12" data-bind="foreach: resourceRows">
            <div class="row" data-bind="foreach: $data">
                <a data-bind="attr: { href: Url }">
                    <div class="resource-detail">
                        <p data-bind="text: FriendlyName"></p>   
                        <h6 data-bind="text: Title"></h6>
                    </div>
                </a>
            </div>
            <div class="clearfix"></div>
        </div>
    </div>
</div>

我对方面的约束:

<script type="text/html" id="facet-checkbox-template">
    <input type="checkbox" data-bind="attr: { id: name.replace(' ', '-').toLowerCase()}, checked: IsChecked " />
    <label data-bind="text: name, attr: { for: name.replace(' ', '-').toLowerCase() }"></label>
    <div class="clearfix"></div>
</script>

<div data-bind="template: { name: 'facet-checkbox-template', foreach: facets }"></div>

2 个答案:

答案 0 :(得分:0)

更改

self.resources = ko.observable();
self.facets = ko.observable();

self.resources = ko.observableArray();
self.facets = ko.observableArray();

我很确定会解决它。常规observable跟踪内部值,但observableArray将跟踪是否从数组中添加/删除对象。由于您没有使用过,因此永远不会通知您将新数据推送到数组中。参考:http://knockoutjs.com/documentation/observableArrays.html

编辑:我发现了另一件可能需要修复的事情:

self.selectAll = ko.computed({
    read: function () {
        // Below, self.facets should probably be self.facets(). self.facets is an observable, not an array
        var firstUnchecked = ko.utils.arrayFirst(self.facets, function (item) {
            return item.IsChecked() == false;
        });
        return firstUnchecked == null;
    },
    write: function (value) {
        // Below, self.facets should probably be self.facets(). self.facets is an observable, not an array
        ko.utils.arrayForEach(self.facets, function (item) {
            item.IsChecked(value);
        });
    }
});

答案 1 :(得分:0)

男孩,多么令人尴尬......我有我的函数调用来获取我的document.ready()之外的所有资源。这就是为什么没有任何东西填充,而在我页面的顶部。