Почему this.set не работает, используется в этой функции Javascript в Kendo

У меня есть приложение Kendo Mobile, и я пытаюсь написать ViewModel, используя шаблон модуля выявления.

В моем HTML я связываю список с gamesListDataSource. При получении я извлекаю данные, а затем мне нужно сообщить мне HTML, что источник данных изменился. Этот код все работает нормально (хотя я думаю, что я делаю что-то здесь, так как я мог бы каким-то образом выставить источник данных напрямую).

1) если я закомментирую эту строку: GamesListViewModel.refreshGamesList(dataSource); и раскомментируйте эту строку: this.set("gamesListDataSource", dataSource); так что он вызывается непосредственно в функции loadGamesList, затем он падает с "Uncaught TypeError: Object [object Object] не имеет метода 'set'"

Я предполагаю, что это как-то связано с тем, что fetch() является асинхронным, но я не понимаю, почему вызов другой функции работает нормально?

gamesList.js

(function (global) {
    var GamesListViewModel,
        app = global.app = global.app || {};

    GamesListViewModel = kendo.observable({
        gamesListDataSource: {},

        refreshGamesList: function (dataSource) {
            //this works fine if called in a function, but not inline in loadGamesList()
            this.set("gamesListDataSource", dataSource);
        },

        loadGamesList: function () {
            dataSource = new kendo.data.DataSource({
                transport: {
                    read: {
                        url: app.configuration.getGamesListUrl,
                        dataType: "json",
                    }
                }

            });
            console.log(dataSource.total());
            dataSource.fetch(function () {
                console.log('done reading');
                console.log(dataSource.total());

                //uncommenting this line below breaks it
                //this.set("gamesListDataSource", dataSource);
                GamesListViewModel.refreshGamesList(dataSource);
            });
        },

        onInit: function (e) {
            console.log("GamesListViewModel - onInit");
            GamesListViewModel.loadGamesList();
        }
    });

    app.gamesListService =
    {
        viewModel: GamesListViewModel
    };
})(window);

gamesList.html

<!DOCTYPE html>
<html>
    <head>
        <title>Games</title>
    </head>
    <body>
        <div id="tabstrip-home"
             data-role="view"
             data-title="Poker Games"
             data-init="app.gamesListService.viewModel.onInit" 
             data-model="app.gamesListService.viewModel">

            <div data-role="button" data-bind="click:loadGamesList">Do it</div>

            <ul class="games-list"
                data-role="listview"
                data-bind="source: gamesListDataSource"
                data-template="games-template">
            </ul>

        </div>

        <script type="text/x-kendo-template" id="games-template">
            <div class="product">
                <h4>#:Title#</h4>
            </div>
        </script>
    </body>
</html>

1 ответ

Решение

Взгляните на метод выборки источника данных в kendo.data.js; по сути, он делает что-то вроде этого:

fetch: function (callback) {
    var that = this;

    ...

    if (fetchSuccessful) {
        if (callback) {
            // as you can see here, when invoking your callback,
            // the code binds "this" to the data source instance
            // you called .fetch() on
            callback.call(that, e);
        }
    }
},

Этот шаблон используется во многих других методах, которые принимают обратные вызовы - с Kendo UI вы можете вообще ожидать this чтобы быть виджетом, на котором вы вызвали метод. Ваш другой звонок работает, потому что вы ссылаетесь на GamesListViewModel переменная вместо this, Вы также можете сделать:

GamesListViewModel.set("gamesListDataSource", dataSource);
Другие вопросы по тегам