JsViews: элемент пользовательского интерфейса с неправильными значениями после наблюдаемого обновления

JsViews-отличная библиотека. И я работаю с ним уже некоторое время.

Но я все еще не могу найти, почему, черт возьми, этот вызов события не будет работать.

Данные после сортировки правильные и arr хороший.

sortTiers: function () {
var arr = this.StructureActivitiesTiers.slice()
          .sort(function (a, b) { return parseFloat(a.TierTo) - parseFloat(b.TierTo); });
            for (var i = 0; i < arr.length; i++) {
                arr[i].TierTo = parseFloat(arr[i].TierTo);
                arr[i].TierFrom = (i == 0 ? 0 : arr[i - 1].TierTo)
            }
            $.observable(this.StructureActivitiesTiers).refresh(arr);
}

Шаблон:

{^{for StructureActivities}}
<tr>
 <td><input type="text" data-link="Currency"></td>
 <td><input type="text" data-link="Price"></td>
</tr>
{^{for StructureActivitiesTiers}}
<tr>
<td></td>
  <td>From: <input disabled data-link="TierFrom" type="text">&emsp;&emsp;
    To: <input type="text" data-link="TierTo">
  </td>
</tr>
{{/for}}
<tr>
<td>
  <button data-link="{on 'click' ~sortTiers}"/>
</td>
<td> 
</td>
</tr>
{{/for}}

Спасибо!

1 ответ

  1. Ну ладно. То, что вы делаете, сначала сортирует StructureActivitiesTiersмассив, затем изменяет его значения ненаблюдаемо, затем вызывает $.observable(this.StructureActivitiesTiers).refresh(arr);.

    Эффект refresh(arr)заключается в том, чтобы сначала определить, действительно ли объекты в новом массиве arrссылаются на существующие объекты в StructureActivitiesTiersмассиве. Если это так, он просто перетасует отрисованные представления, чтобы поместить их в правильном порядке, и не будет повторно отрисовывать каждый из них. Таким образом, не наблюдаемые изменения свойств игнорируются.

    Это можно исправить, сделав изменения свойства наблюдаемыми до или после выполнения вызова обновления массива:

    for (var i = 0; i < arr.length; i++) {
      $.observable(arr[i]).setProperty({
        TierTo: parseFloat(arr[i].TierTo),
        TierFrom: i == 0 ? 0 : arr[i - 1].TierTo
      });
    }
    $.observable(this.StructureActivitiesTiers).refresh(arr);
    

    или:

    $.observable(this.StructureActivitiesTiers).refresh(arr);
    for (var i = 0; i < arr.length; i++) {
      $.observable(arr[i]).setProperty({
        TierTo: parseFloat(arr[i].TierTo),
        TierFrom: i == 0 ? 0 : arr[i - 1].TierTo
      });
    }
    

    Посмотреть https://jsfiddle.net/ertsu5qc/4/ .

    Альтернативно вы можете заполнить arrс новыми объектами:

    for (var i = 0; i < arr.length; i++) {
      arr[i] = {
        TierTo: parseFloat(arr[i].TierTo),
        TierFrom: i == 0 ? 0 : arr[i - 1].TierTo
      };
    }
    $.observable(this.StructureActivitiesTiers).refresh(arr);
    

    Теперь refresh(arr)вызов находит новые объекты, а не ссылки на существующие, поэтому он удаляет старые представления для каждого элемента и вставляет новые для новых элементов (очевидно, отображает их полностью).

    Посмотреть https://jsfiddle.net/ertsu5qc/5/ .