简体   繁体   中英

Knockout computed property not binding

I am having trouble binding a computed variable using Knockout. Here is some simplified code of the problem. I have a computed variable selectedClientStrategy which should be an array of strategy objects when set. I can see it in the pre data-bind but it is not populating the second select in the page. Any help appreciated.

<div>

    <select data-bind="visible:dealClients().length > 0, options: dealClients, optionsText: 'clientName', value: selectedClient"></select>
    <br />
    <select data-bind="visible:selectedClientStrategies().length > 0, options: selectedClientStrategies, optionsText: 'strategyName'"></select>

</div>
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>

<script>
//client object
function client(data) {
    var jClient = $.parseJSON(data);

    this.clientId = ko.observable(jClient.documentId);
    this.clientName = ko.observable(jClient.company.companyName);
    this.clientDescription = ko.observable(jClient.company.companyDescription);
    this.clientStrategies = ko.observableArray([]);
    for (var i = 0; i < jClient.strategies.length; i++)
    {
        this.clientStrategies.push(new strategy(jClient.strategies[i]));
    };
}
//strategy object
function strategy(data) {

    this.strategyId = ko.observable(data.documentId);
    this.strategyName = ko.observable(data.strategyName);
    this.strategyClientId = ko.observable(data.clientId);
}
// Overall viewmodel for this screen, along with initial state
function dealViewModel() {
    var self = this;
    self.dealClients = ko.observableArray([]);
    self.selectedClient = ko.observable();
    self.selectedClientStrategies = ko.computed(function ()
    {

        if (self.selectedClient())
        {
            return self.selectedClient().clientStrategies;
        }
        else
        {

            return [new strategy({strategyId: "", strategyName: "", strategyClientId: ""})];
        }

    }
    )

    self.clientData = ko.observable();

    $.getJSON
        (
            '/api/client',
            function (data)
            {
                for (var i = 0; i < data.length; i++)
                {
                    self.dealClients.push(new client(data[i]));
                };
            }
        )
}

ko.applyBindings(new dealViewModel());

sample JSON from ajax call

[
  {
  documentId: "client_1",
  documentType: "client",
  company: {
    documentId: "company_97",
    documentType: "company",
    companyName: "gg",
    companyDescription: ""
    },
  strategies: [
    {
      documentId: "strategy_1",
      documentType: "strategy",
      clientId: "client_1",
      strategyName: "af"
    },
    {
      documentId: "strategy_10",
      documentType: "strategy",
      clientId: "client_1",
      strategyName: "gdf"
    },
    {
      documentId: "strategy_2",
      documentType: "strategy",
      clientId: "client_1",
      highriseId: "fi",
      strategyName: "fi"
    },
    {
      documentId: "strategy_3",
      documentType: "strategy",
      clientId: "client_1",
      strategyName: "rp"
    },
    {
      documentId: "strategy_4",
      documentType: "strategy",
      clientId: "client_1",
      strategyName: "ad"
    },
    {
      documentId: "strategy_5",
      documentType: "strategy",
      clientId: "client_1",
      strategyName: "Df"
    },
    {
      documentId: "strategy_6",
      documentType: "strategy",
      clientId: "client_1",
      strategyName: "g"
    },
    {
      documentId: "strategy_7",
      documentType: "strategy",
      clientId: "client_1",
      strategyName: "eme"
    },
    {
      documentId: "strategy_8",
      documentType: "strategy",
      clientId: "client_1",
      strategyName: "ff"
    },
    {
      documentId: "strategy_9",
      documentType: "strategy",
      clientId: "client_1",
      strategyName: "ggr"
    }
  ]
}
,
{
  documentId: "client_2",
  documentType: "client",
  company: {
    documentId: "company_100",
    documentType: "company",
    companyName: "Mmm",
    companyDescription: "mm"

  },
  strategies: [
    {
      documentId: "strategy_11",
      documentType: "strategy",
      clientId: "client_2",
      strategyName: "GG"
    },
    {
      documentId: "strategy_12",
      documentType: "strategy",
      clientId: "client_2",
      strategyName: "EM"
    },
    {
      documentId: "strategy_13",
      documentType: "strategy",
      clientId: "client_2",
      strategyName: "DG"
    },
    {
      documentId: "strategy_14",
      documentType: "strategy",
      clientId: "client_2",
      strategyName: "GG "
    },
    {
      documentId: "strategy_15",
      documentType: "strategy",
      clientId: "client_2",
      strategyName: "mm"
    }
  ]
}
]

The selectedClientStrategies is dependent on the selectedClient and the selectedClient is not initialized, so in this case you should return an array of strategy: return [new strategy({strategyId: "", strategyName: "", strategyClientId: ""})]; and it should be: return self.selectedClient().clientStrategies(); in case the selectedClient has value.

the reason is that options must be bound with an array of objects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM