问题
Messing around with a bacon.js. I'd like to keep a running total of values in a group of text inputs. The example on the github site uses .scan
and an adder function, which works fine for the example because it's using -1 and +1 in the stream. But I'd like values to be removed from the stream if they are edited, so the .scan
solution won't really work for me or I'm not doing it right.
Markup:
<ul style="repeat-direction: vertical; list-style-type: none;">
<li><input data-group="0"></li>
<li><input data-group="0"></li>
<li><input data-group="0"></li>
</ul>
<ul style="repeat-direction: vertical; list-style-type: none;">
<li><input data-group="1"></li>
<li><input data-group="1"></li>
<li><input data-group="1"></li>
</ul>
So the solution that I have is to run through the inputs whenever there's a throttled keyup event and then update a span when it changes.
groupZeroEvents = events.filter (val) ->
Math.floor(val[0]) == 0 # the stream contains the group the input belongs to
groupZeroEvents.onValue (val) ->
sum = 0
$("input[data-group='0']").each (i,el) ->
sum += Math.floor($(el).val())
$('span#sum-g0').html(sum)
It works fine, but seems lame -- feels like I'm missing a way to use Bacon.js
correctly.
回答1:
The sum depends on the current value of multiple inputs. If you model these inputs as Properties, you'll come to a nicer solution:
function sum(xs) { return _.reduce(xs, (function(x,y) {return x + y}), 0); }
// array of Properties representing the value of each group-zero-element
var groupZeroValues = $("input[data-group=0]").map(function(index, elem) {
return $(elem).asEventStream("keyup")
.map(function(e) { return parseInt($(e.target).val()); })
.toProperty(0)
}).toArray();
// sum Property
var groupZeroSum = Bacon.combineAsArray(groupZeroValues).map(sum)
// assign Property value to the "text" method of the sum element
groupZeroSum.assign($("#sum-g0"), "text")
I didn't have time to actually try this, but the idea will definitely work.
来源:https://stackoverflow.com/questions/14590210/how-should-i-keep-a-running-total-of-several-values-with-bacon-js