質問

Basically, what I am trying to achieve is to populate a dropdown based on the value of another dropdown in Knockout.js

My view code(stripped obviously):

            <div data-bind="with: chosenMailData">
                <table id="tabl-1234" class="mails">
                    <thead><tr><th>Destination</th><th>Hotel</th></tr></thead>
                    <tbody data-bind="template: { name: 'iti-template', foreach: objects, afterRender: $root.myPostProcessingLogic }">
                </table>
            </div>

            <script type="text/html" id="iti-template">
                <tr>
                    <td><select class="desti" data-bind="options: $root.destinations, value: destination.name"></select></td>   
                    <td><select data-bind="options: $root.generall(), value: $root.generall()"></select></td>
                </tr>
            </script>

My View-Model(again stripped-down):

            self.destinations=['Kerela', 'Shoghi, Himachal Pradesh', 'Kasauli, Himachal Pradesh'];

            self.myPostProcessingLogic = function(elements) {
                this.generall = ko.computed(function() {
                    $('.desti').each(function(i, obj) {
                        stayOptions = [];
                            $.getJSON("http://127.0.0.1:8000/api/hotel?format=json&location__name="+obj.value, function(data) {
                                    $.each(data.objects, function(i, item){
                                    stayOptions.push(item.name);
                                    });
                                });
                    });
                    return stayOptions;
                }, this);
            }

Inserting alert() in this.generall() shows that stayOptions does get populated with the values I want in it. It is getting that array to get displayed in select options for corresponding row in Hotels column which is the problem.

Probably I am making a really dumb mistake but I have been looking at the code for a long time now and nothing comes to mind. Please advise.

EDIT: I am doing this too at the beginning of my view-model:

            self.generall = ko.observableArray();
役に立ちましたか?

解決

When calling methods, the this variable gets assigned on invocation.

var f = $root.myPostProcessingLogic;
f(); // this will not set 'this' to '$root'

The above is essentially what knockout is doing, and this makes this be bound to something else inside myPostProcessingLogic(). You have already defined the scoped self variable, so this is easy to fix.

Another problem is that, reassigning observables won't preserve any subscribers, and any dependant observables won't update.

self.generall = ko.observableArray();
self.myPostProcessingLogic = function(elements) {
    self.generall.removeAll();
    $('.desti').each(function(i, obj) {
        $.getJSON("http://127.0.0.1:8000/api/hotel?format=json&location__name="+obj.value, function(data) {
            $.each(data.objects, function(i, item){
                self.generall.push(item.name);
            });
        });
    });
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top