Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout - How to reset Dynamic observable array with new value

I can't reset observable array with new value am using some lazy loading Technic. I can clear but can't reset, but it not allowing me to add new dynamic value.

fiddle http://jsfiddle.net/kspxa8as/

js

var i = 1;
            optionsProvider = function(self) {
                var self = self || {};
                self.options = {};
                self.get = function(name, initialValue) {
                    if (!self.options[name]) {
                        console.log("Called - " + name);
                        self.options[name] = ko.observableArray([initialValue]);
                        var requestHeader = '';
                        setTimeout(function() {
                            var aa = [{name: "plant 1" + i, selected: true}, {name: "palnt 2" + i, selected: false}];
                            self.options[name](aa);
                            i++;
                        }, 2000);
                    }
                    return self.options[name];
                };
                return self;
            };
            ViewModel = function() {
                var self = this;
                var k = 1;
                var ob = new optionsProvider(self);
                self.PlantSelected = ob.get("name" + k, '');
                self.fillNewSelect = function() {
                    self.PlantSelected.removeAll();
                    self.PlantSelected().push(ob.get("name" + k, ''));
                    k++;
                };
            };
            ko.applyBindings(new ViewModel());

HTML

<select class="n_imported_country"                     
            data-bind="options: PlantSelected,
                               optionsText :'name'   
            "
            >
    </select>
    <div data-bind="click: function(){
         $root.fillNewSelect();
    }">click to fill new select value</div>

I am a newbie to knockout, great welcome your answers.

like image 719
muhammed uvais Avatar asked Nov 09 '22 12:11

muhammed uvais


1 Answers

I recommend the use of a promise library to handle the asynchronous Ajax load of new items. I've used jQuery's implementation in the sample below. Notice how optionsProvider no longer requires any dependency on the viewmodel.

var optionsProvider = function (name, initialValue) {
    return function () {
        return $.get("/target/url", {parameter: "value"})
        .fail(function () {
            console.log("request to get new items failed", arguments);
        });
    };
};

var ViewModel = function () {
    var self = this,
        k = 1,
        ob = optionsProvider("name" + k, '');

    self.PlantSelected = ko.observableArray([]);
    self.fillNewSelect = function () {
        ob().then(function (newData) {
            var p = self.PlantSelected;
            p.removeAll();
            p.push.apply(p, newData);
        });
    };

    // init
    self.fillNewSelect();
};
ko.applyBindings(new ViewModel());

The second change to mention is the way to push new objects into an array. .push() supports an argument list:

arr.push('a', 'b', 'c')

If you have an array of items you want to push (for example a JSON result), you would use .apply(), otherwise you would push the array itself as the first item:

arr.push.apply(arr, ['a', 'b', 'c']);

Observable arrays in knockout support the same usage.

Compare: http://jsfiddle.net/kspxa8as/6/

like image 119
Tomalak Avatar answered Nov 14 '22 23:11

Tomalak