Search code examples
javascriptknockout.jsknockout-3.0revealing-module-pattern

knockout setting computed within javascript revealing module pattern


I am using knockout with revealing module pattern. I want to pass in an observable by reference and have its' value based on a computed. This issue is it is not getting passed into the pattern by reference...it seems like it is getting passed in by value.

listPersonClientSelect is observable() and i want to pass this into a js function and establish a computed calculation on listPersonClientSelect (you can see in the code below that i am passing in the observable as a parameter in the init and i want to set this observable value to the computed based on the changes in select2Data()

init function is called with the following....so what the end result is

self.assigneePersonSetupKO.listPersonClientSetup does show the result of the computed however what I really want is self.assignees() to show the changes (value of the computed)

Is it possible to pass self.assignees into the js revealing patting by reference?

self.assigneePersonSetupKO = new PersonSetupKO();
self.assigneePersonSetupKO.init(self.assignees);

var PersonSetupKO = function () {
    "use strict";
    
    //var self = this;
    var select2Data = ko.observable(''),
        initialOptions = [],
        initialSelectedOptions = [],        
        listPersonClientSelect = ko.observable(),
                
        init = function (listPersonClientSelect) {
            this.initialOptions = $.map(listPersonClientSelect(), function (item) {
                return { DisplayName: item.DisplayName(), Gen: item.Id() }
            });

            this.initialSelectedOptions = $.map(listPersonClientSelect(), function (item) {
                return item.Gen();
            });

            this.select2Data($.map(listPersonClientSelect(), function (item) {
                return { text: item.DisplayName(), id: item.Id() };
            }));

            
            this.listPersonClientSelect = ko.computed(function () {
                var results = $.map(select2Data(), function (item) {
                    return {
                        DisplayName: ko.observable(item.text),
                        Id: ko.observable(item.id)
                    }
                });
                return results;
            });
        };

    return {       
        init: init,
        select2Data: select2Data,
        initialOptions: initialOptions,
        initialSelectedOptions: initialSelectedOptions,
        listPersonClientSelect: listPersonClientSelect
        
    };

};


Solution

  • Observables are always passed by reference. So init does receive a reference to the original observable. You just need to write to it:

    this.updateListPersonClientSelect = ko.computed(function () {
        var results = $.map(select2Data(), function (item) {
            return {
                DisplayName: ko.observable(item.text),
                Id: ko.observable(item.id)
            }
        });
        listPersonClientSelect(results);
    });