延迟敲除结合评估

时间:2014-08-25 05:07:10

标签: jquery-mobile knockout.js

在这里淘汰新手。我有一个显示客户信息的页面。

1st div should be displayed when customer info is present.
2nd div should be displayed when no customers are displayed

//1st Div
<div id="custInfoList" data-role="content"
    data-bind="foreach: customers, visible : customers().length > 0">
    <p data-bind="text: $data.info"></p>
</div>
//2nd Div
<div id="empty" data-role="content"
    data-bind="visible: customers().length === 0 ">
    <p>No Customer Information</p>
</div>

我的模型是这样的:

var myModel = {
    customers : ko.observableArray();
}

..在页面加载时我添加了这个逻辑:

//On Page Load, call AJAX to populate the customers
    //customers = {jsonData}

我的网页正在使用jQuery Mobile。我唯一的问题是,首次显示页面时,会显示第二个div。当Ajax json数据返回时,隐藏它的位置。

当ajax仍在加载且数据尚未返回时,是否可以隐藏第二个div?

更新2

在相关的说明中,我尝试了我刚从网上阅读的KO HTML模板

<!-- ko if: customers().length -->
    <div id="custInfoList" data-role="content"
        data-bind="foreach: customers, visible : customers().length > 0">
        <p data-bind="text: $data.info"></p>
    </div>
<!-- /ko -->
<div id="empty" data-role="content"
    data-bind="if: customers().length === 0">
    <p>No Customer Information</p>
</div>

但仍然不成功。有什么想法缺少什么?

更新3 我尝试更新@shriek在他的小提琴中展示的内容http://jsfiddle.net/t0wgLt79/17/

<!-- ko if: customers() -->
<div id="custInfoList" data-role="content" data-bind="foreach: customers">
    <p data-bind="text: $data"></p>
</div>
<!-- /ko -->
<div id="empty" data-role="content" data-bind="if: customers().length === 0" style="display: none;">
    <p>No Customer Information</p>
</div>
<button data-bind="click:popCustomers">Populate</button>

我的JS:

$.support.cors = true;
var test = {
    customers: ko.observableArray(),
    popCustomers: function () {
        for (var i = 0; i < 3; i++) {
            this.customers.push(i);
        }
    },
    popByAjax: function () {
        console.log("Calling JSON...");
        $.getJSON("http://api.openweathermap.org/data/2.5/weather?id=2172797", function (data) {
            console.log(data);
            if (data.sys) {
                this.customers.push(data.sys.country);
                console.log("Loaded");
            }
        }.bind(this));
    }
};
test.popByAjax();
ko.applyBindings(Object.create(test));

在初始加载时,&#34; AU&#34;被展示。现在改变天气?id = 2172797进入天气?id = 21727971使其无效。我注意到没有客户信息显示。

3 个答案:

答案 0 :(得分:1)

你看到第二个div和第一个div因为你的DOM元素的淘汰applyBinding尚未发生,这意味着visible绑定尚未被评估,因此不会相应地隐藏任何元素,使其处于默认状态(将显示)

要克服此行为,您只需要向默认情况下隐藏的那些元素添加style="display: none;",然后visible绑定将删除display: none评估为true

所以你的代码应该是这样的

//1st Div
<div id="custInfoList" data-role="content"
    data-bind="foreach: customers, visible : customers().length > 0">
    <p data-bind="text: $data.info"></p>
</div>
//2nd Div
<div id="empty" data-role="content"
    data-bind="visible: customers().length === 0" style="display: none;">
    <p>No Customer Information</p>
</div>

和btw,使用visibleif绑定无关紧要,因为问题不在于绑定本身。

答案 1 :(得分:1)

正如上面的评论中提到的,对于更新3 display:none是无关紧要的,因为if已经对数据绑定进行了处理。

第二件事是observableArray收到错误回复后必须清空,因为隐藏/显示是基于observableArray长度的比较。

代码: - http://jsfiddle.net/4hmqdsup/

答案 2 :(得分:0)

我猜你在//customers = {jsonData}做错了。

要更新ko.observable,您需要使用customers(jsonData),而不是customers = jsonData

ko.observable()返回一个函数,setter为customers(newValue),getter为customers(),你需要在setter和getter中显式使用函数调用。