2015-10-06 3 views
4

У меня есть редактируемые данные в таблице с суммами для строк и столбцов, которые должны быть рассчитаны.Aurelia: Вычислено/Наблюдается в repeat.for

Example of table

Как я хотел бы иметь простой HTML-код, я использую repeat.for для создания строки таблицы. Чтобы построить сумму, я использую функцию, которая была наилучшим способом, который я придумал до сих пор.

К сожалению, суммы не обновляются таким образом, когда я изменяю значения. Функции Getter вычислялись бы, но они не могут принимать параметр.

Я знаю, что могу написать что-то вроде $ {$ parent.data [y] ['Q1'] + $ parent.data [y] ['Q2'] + ...}, но это довольно длинное и что «Q1» в этом примере будет чем-то динамичным в реальной жизни. И для сумм столбцов у меня будет 15 строк, которые нужно суммировать - я бы предпочел не писать инструкцию для суммы в html для этого.

Я смотрел на наблюдателя, но не понял, как я могу использовать это для своего дела. Я думаю, что это довольно простой szenario, поэтому я надеюсь, что есть хорошее решение для чего-то подобного в Aurelia.

test.js

export class Test { 
    data = { 
     "2015": { "Q1": 7318, "Q2": 6215, "Q3": null, "Q4": 3515 }, 
     "2016": { "Q1": 1234, "Q2": 2345, "Q3": 3345, "Q4": 3000 }, 
     "2017": { "Q1": 4233, "Q2": 999, "Q3": 1234, "Q4": 3268 }, 
     "2018": { "Q1": 7375, "Q2": 4415, "Q3": 8415, "Q4": 1005 }, 
     "2019": { "Q1": null, "Q2": 5698, "Q3": 1254, "Q4": 6635 } 
    }; 

    years() { 
     return Object.keys(this.data); 
    } 

    sumY(y) { 
     var sum = 0; 
     Object.values(this.data[y]) 
      .forEach(function(item){ 
       sum += item; 
      }); 
     return sum; 
    } 

    sumQ(q) { 
     var sum = 0; 
     Object.values(this.data) 
      .forEach(function(item) { 
       sum += item[q]; 
      }); 
     return sum; 
    } 
} 

test.html

<template> 
    <table> 
     <thead> 
      <tr> 
       <td>Year</td> 
       <td>Q1</td> 
       <td>Q2</td> 
       <td>Q3</td> 
       <td>Q4</td> 
       <td>Sum</td> 
      </tr> 
     </thead> 
     <tbody> 
      <tr repeat.for="y of years()"> 
       <td>${y}</td> 
       <td><input type="text" value.bind="$parent.data[y]['Q1']" /></td> 
       <td><input type="text" value.bind="$parent.data[y]['Q2']" /></td> 
       <td><input type="text" value.bind="$parent.data[y]['Q3']" /></td> 
       <td><input type="text" value.bind="$parent.data[y]['Q4']" /></td> 
       <td class="ansatz">${$parent.sumY(y)}</td> 
      </tr> 
     </tbody> 
     <tfoot> 
      <tr> 
       <td>Sum</td> 
       <td>${sumQ("Q1")}</td> 
       <td>${sumQ("Q2")}</td> 
       <td>${sumQ("Q3")}</td> 
       <td>${sumQ("Q4")}</td> 
      </tr> 
     </tfoot> 
    </table> 
</template> 

ответ

4

При связывании-поведения имеют отпускание мы сможем использовать «сигнал» привязку поведения назвать привязки значения и привязки суммы. Затем мы сможем «сигнализировать» привязки сумм для обновления при изменении привязок значений.

В текущей версии Aurelia вы можете добавить аргумент «сигнал» к выражениям привязки sumY и sumQ (нет необходимости добавлять аргумент arg к фактическим методам в модели представления). Тогда в показах модели добавьте следующий код в «сигнале» крепления на интервале:

signal = 0; 
attached() { 
    this.interval = setInterval(() => this.signal++, 120); 
} 
detach() { 
    clearInterval(this.interval); 
} 

Вот рабочий plunker демонстрирует эту технику: http://plnkr.co/edit/3sXQM0


Использования ObserverLocator потребует более изменения вашего кода. Вам нужно будет позвонить var observer = observerLocator.getObserver(obj, propertyName) для каждого из свойств, привязанных к значению ввода. Затем вам нужно позвонить var dispose = observer.subscribe(::this.computeSums). Затем вам нужно будет реорганизовать ваши функции сумм в фактические свойства, чтобы computeSums мог обновить их значение, которое в свою очередь вызовет привязку суммы для обновления. Наконец, вам нужно будет отказаться от подписки в отключенном методе.

+0

Спасибо, @Jeremy. Когда можно ожидать выхода функции привязки-поведения? С бета-версией? – doeck

+0

yep мы нацеливаем бета-версию –