Search code examples
javascriptjqueryjsviews

jsviews - Update field of array element


I have an issue with jsviews. I want to bind an array of elements. Each element is an object. Elements are added dynamicaly. Value of one field of each element computes base on another field. How is it posiible to do without refreshing array every time?

js:

model = {
    elements: []
};
$(function() {
    $.when($.templates('#tmpl').link('#container', model)
            .on('click', '#addElement', function () {
                $.observable(model.elements).insert({});
            })
    ).done(function() {
        $.observe(model, 'elements', function(e, eventArgs) {
            if (eventArgs.change === 'insert') {
                eventArgs.items.forEach(function(addedElement) {
                    $.observe(addedElement, 'value1', function(e) {
                        var element = e.target;
                        element.value2 = 'Value1 is ' + element.value1;
                        $.observable(element).setProperty('value2', element.value2);
                        $.observable(model).setProperty('recent', element.value1);
                    });
                });
            }
        });
    });
});

html:

<div id="container"></div>

<script id="tmpl" type="text/x-jsrender">
    <input id="addElement" type="button" value="add new element"/>
    <div id="box">
        {^{for elements tmpl="#elementTmpl"/}}
    </div>
    <input type="text" data-link="recent" />
</script>

<script id="elementTmpl" type="text/x-jsrender">
    <div>
        <input name="input1" data-link="value1" />
        <input name="input2" data-link="value2" />
    </div>
</script>

I created jsfiddle that illustrates the problem.


Solution

  • You can use ObserveAll(): http://www.jsviews.com/#observeAll.

    Every time the element.value1 changes, you update the calculated properties element.value2 and model.recent.

    I updated your fiddle here https://jsfiddle.net/1rjgh2sn/2/ with the following:

    $.templates('#tmpl').link('#container', model)
        .on('click', '#addElement', function () {
            $.observable(model.elements).insert({});
        });
    $.observable(model).observeAll(function(e, eventArgs) {
        if (eventArgs.change === "set" && eventArgs.path === "value1") {
            var element = e.target;
            $.observable(element).setProperty('value2', 'Value1 is ' + element.value1);
            $.observable(model).setProperty('recent', element.value1);
        }
    });