Почему 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);