根据条件淘汰突出显示行

Knockout highlighting row on condition basis

我正在尝试完成以下代码以根据条件突出显示行

self.highLightRow = function (row) {
   var today = moment(new Date());
   if (row.DueDt() !== '') {
        var d = moment(row.DueDt(), 'MM/DD/YYYY');
        if (d && d.isValid()) {
       if (today.diff(d, 'days') < 10) {
       return '#FFA500';
    }
    else if (today.diff(d, 'days') > 10) {
        return '#fdbcb4';
    }
  }
  else {
    return '#FFFFFF';
}
}
else {
 return '#FFFFFF';
}
    }

没有按预期工作,我的table如下

<table>
    <tbody data-bind="foreach: people">
    <tr data-bind="css :{ colorRow:highLightRow ($people) }">
        <td data-bind="text: name"></td>
        <td data-bind="text: DueDt"></td>
    </tr>
    </tbody>
</table>

当我编写 3 个不同的条件并绑定时,它起作用了

<table>
    <tbody data-bind="foreach: people">
    <tr data-bind="css :{ white:$root.noColor($people) }">
        <td data-bind="text: name"></td>
        <td data-bind="text: DueDt"></td>
    </tr>
    </tbody>
</table>

我希望它具有单一功能。

$(document).ready(function () {
window.peopleVM= new peopleViewModel();
window.peopleVM.Init();
});
function peopleViewModel() {
     var self = this;
     self.employeeList = ko.observableArray();
     self.Init = function () {
     ko.applyBindings(self, $("#myDiv")[0]);
    }
}

我正在调用 ajax 来加载数据,如下所示

self.LoadEmployees = function () {
        self.IsLoaded(false);
        var jqxhr = $.get(
            window.WebApiBase + "GeData",
            function (data) {
                self.IsLoaded(true);
                if (data && data.length > 0) {
                    $.each(data, function (index, item) {
                        if (item) {
                            self.employeeList.push(ko.mapping.fromJS(item));
                        }
                    });
                    self.IsLoading(false);
                }
                else {
                    self.IsLoading(false);
                }
            })
        .fail(function (jqXHR, status, errorThrown) {

        });
        return jqxhr;
    }

您仍在考虑命令式术语中的 Knockout(即 "what would I need to do in jQuery?")。那没有用。不要尝试 "call a function for every row",而是考虑 "calculate a value and bind the view to it".

  1. 您有一个人员列表。
  2. 该列表中的每个人都有一些属性,例如 nameDueDt
  3. 对于每个这样的人,可以从截止日期计算出紧急程度("due soon"、"due later"、"unknown")。
  4. 行颜色是该紧急值的结果。

1 和 2 是数据模型的基本属性。 3 由视图模型提供。 4 在视图中通过 CSS.

处理

当每个 Person 对象计算自己的 urgency 值时:

// viewmodel for a single person
function Person(data) {
  var self = this;
  
  self.name = data.name;
  self.DueDt = data.DueDt;
  self.isSelected = ko.observable(false);
  self.urgency = ko.pureComputed(function () {
    var d = moment(self.DueDt, 'MM/DD/YYYY');
    if (d.isValid()) {
      return d.diff(moment(), 'days') < 10 ? 'dueSoon' : 'dueLater';
    }
  });
}

// viewmodel for the overall list of people
function PersonList(data) {
  var self = this;
  
  self.people = ko.observableArray(data.people.map(function (p) {
    return new Person(p);
  }));
}

// sample data and viewmodel binding
var dataFromServer = {
  people: [
    {name: 'John Doe', DueDt: moment().add(20, 'days').format('MM/DD/YYYY')},
    {name: 'Jane Doe', DueDt: moment().add(5, 'days').format('MM/DD/YYYY')},
    {name: 'Jon Snow', DueDt: ''},
  ]
};
var vm = new PersonList(dataFromServer);
ko.applyBindings(vm);
table { border-collapse: collapse; }
td { padding: 3px; }
tr.dueSoon { background-color: #FFA500 }
tr.dueLater { background-color: #fdbcb4 }
tr.selected { background-color: red!important; color: white }
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.0/knockout-debug.js"></script>

<table>
  <thead>
    <tr>
      <td></td>
      <td>Name</td>
      <td>Due Date</td>
      <td>Selected</td>
      <td>Urgency</td>
    </tr>
  </tbody>
  <tbody data-bind="foreach: people">
    <tr data-bind="class: urgency, css: {selected: isSelected}">
      <td><input type="checkbox" data-bind="checked: isSelected"></td>
      <td data-bind="text: name"></td>
      <td data-bind="text: DueDt"></td>
      <td data-bind="text: isSelected"></td>
      <td data-bind="text: urgency"></td>
    </tr>
  </tbody>
</table>

...然后视图变得非常简单明了。

请注意,class 绑定是 Knockout 3.5.0 的一项功能。使用早期版本的 Knockout,您可以做到

<tr data-bind="{selected: isSelected, dueSoon: isDueSoon, dueLater: isDueLater}">

并将 isDueSoonisDueLater 计算的布尔属性添加到 Person.

attr 绑定如何

self.highlightRow = function (row) {
        var today = moment(new Date());
        var d = moment(row.DueDtString(), 'MM/DD/YYYY');
        if (d && d.isValid()) {
            if (today.diff(d, 'days') < 10) {
                return 'orange';
            }
            if (today.diff(d, 'days') > 10) {
                return 'melon';
            }
        }
    }

你的 tr 应该是

<tr data-bind="attr: {class: $root.highlightRow($people)}">