1

我正在尝试使用 knockout.js 从 json 中提取一个数字,然后使用 jquery 来调整我的进度条。

它在手动将数字输入到 html 时起作用。使用 json 输入号码时不起作用。

我不确定这是否与敲除/json 和 jquery 冲突,或者我的代码是否错误?

http://jsfiddle.net/infatti/5Q9pK/

// Knockout.js - bring in number of days from json
// -------------------------
// Here's my data model
var viewModel;
$.getJSON('http://echo.jsontest.com/daysDue/50', function (data) {
    viewModel = ko.mapping.fromJS(data);
    ko.applyBindings(viewModel);
});

// Progress Bar - adjust width of progress bar according to number of days
// -------------------------
$('#paging1 ul li').each(function () {
    // progress bar
    // find number of days until due date
    var progBarValue = $(this).find('.days-due').text();
    // limit days due to no more than 100%
    progBarValue = progBarValue > 100 ? 98 : progBarValue;
    // set progress bar width
    $(this).find('.bar').width((100 - progBarValue) +'%');

    // set class of progress bar for color based on days due
    if (progBarValue >= 75) {
       $(this).find('.progress').removeClass('progress-warning progress-danger').addClass('progress-success');
       $(this).find('.DueDate').removeClass('urgent');
    } else  if (progBarValue >= 25 && progBarValue <= 74) {
       $(this).find('.progress').removeClass('progress-success progress-danger').addClass('progress-warning');
       $(this).find('.DueDate').removeClass('urgent');
    } else if (progBarValue <= 24) {
       $(this).find('.progress').removeClass('progress-warning progress-success').addClass('progress-danger');
       $(this).find('.DueDate').addClass('urgent');
    }
});
4

2 回答 2

1

你可以这样做。但是,如果您打算使用 jQuery 操作 DOM,那么在淘汰视图模型中加载数据是没有意义的。您是否考虑过执行以下操作:

对宽度和类使用计算出的 observables

var viewModel;
$.getJSON('http://echo.jsontest.com/daysDue/50', function (data) {
    viewModel = ko.mapping.fromJS(data);
    viewModel.progressBarWidth = ko.computed(function() { 
        return 100 - this.daysDue() + '%'
    }, this);
    viewModel.progressBarClass = ko.computed(function() {
        // note if (100 - x) >= 75, then x <= 25, etc.
        if (this.daysDue() <= 25) { return 'classa'; }
        else if (this.daysDue() > 25 && this.daysDue() <= 75) { return 'classb'; }
        else { return 'classc'; }
    ko.applyBindings(viewModel);
});

现在,你有一个计算出的 observables 来计算你感兴趣的两个值,width 和 class。

DOM 绑定和 CSS

我不确定您的 DOM 是如何构造的,但我会猜测一下。

<!-- container -->
<div data-bind="css: progressBarClass">
    <!-- progress bar -->
    <div class="progress" data-bind="style: { width: progressBarWidth }"></div>
    <!-- text -->
    <div class="DueDate" data-bind="text: daysDue"></div>
</div>

然后剩下的就是在 CSS 中设置类以查找父级进行声明。因此,例如,对于 >= 75 天到期的情况,您可以:

.classa > .progress 
{
    // progress bar style, red or whatever
}
.classa .DueDate
{ 
    // text style, red or whatever
}
于 2013-05-15T22:04:48.453 回答
0

@MatthewJamesDavis 的答案很棒,因为这是一种更简洁的解决问题的方法。

然而,手头的问题和实际问题可能是为什么 jQuerytext()函数没有找到 KO 绑定到跨度的正确“50”。原因是该getJSON方法的触发时间比each设置进度条的实际时间晚。您可以通过将该位包装在一个在适当时间调用的函数中来“解决”这个问题:

var viewModel;
$.getJSON('http://echo.jsontest.com/daysDue/50', function (data) {
    viewModel = ko.mapping.fromJS(data);
    ko.applyBindings(viewModel);
    updateProgressBars(); // NEW
});

function updateProgressBars() { // NEW
    $('#paging1 ul li').each(function () {
        // As before...
    });
} // NEW

现在,在您使用 jQuery 获取数据,进度条会更新。

请参阅此小提琴以进行演示。

尽管如此,最好将适当的进度条属性与 KO 绑定,而不是手动使用 jQuery 进行绑定。

于 2013-05-15T22:44:56.293 回答