我是Knockout.js的新手,并且正在使用它来绑定来自WebAPI调用的数据。 我有一个令人沮丧的情况,即在无限循环中调用getData()方法。经过调试后,当我注释掉console.log(self.activityLogs())时,我发现它消失了。当我把它留在getData方法中时,它不会导致循环问题。
任何人都可以解释这里发生了什么以及为什么会发生这种无限循环?
<tbody data-bind="foreach: activityLogs">
<tr>
<td>b...</td>
</tr>
</tbody>
不确定这是否相关,但这是我在HTML表格中绑定它的方式。
if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
// Activity was brought to front and not created,
// Thus finishing this will get us to the last viewed activity
finish();
return;
}
// Regular activity creation code... }
答案 0 :(得分:1)
我已经为您的案例创建了代码段。我做了一些小改动:添加loopCount
变量以防止在播放期间页面上出现无限循环,并用Promise替换Ajax调用(但从技术上讲它们的行为相同)。
简而言之:您应该执行函数调用 - ko.applyBindings(ActivityLogViewModel);
,而不是ko.applyBindings(ActivityLogViewModel());
。因为否则你会传递&#34;功能对象&#34;这不是Knockout.js期望使用的。由于某种原因,在每次activityLogs
读取之后,它会调用ActivityLogViewModel
并因此触发新的Ajax调用,之后Ajax调用其success
回调并且该过程一次又一次地启动。 / p>
实际上这是一个很好的问题,为什么Knockout以这种方式工作(我们需要深入研究它的源代码),但至少现在我们知道如何防止无限循环问题。
var loopCount = 0;
$(function () {
var ActivityLogViewModel = function () {
console.log('function triggered');
self = this;
self.activityLogs = ko.observableArray([]); //data
getData();
console.log(self.activityLogs()); // when this is here, it goes into infinite loop
function getData() {
if (loopCount > 10) {
return;
}
var requestPromise = $.Deferred();
requestPromise.done(function(data) {
console.log(data);
self.activityLogs(data);
console.log(self.activityLogs());
loopCount++;
});
setTimeout(function() { requestPromise.resolve([1, 2, 3]); }, 100);
}
return {
self: self
}
};
ko.applyBindings(ActivityLogViewModel);
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<tbody data-bind="foreach: activityLogs">
<tr>
<td>Item</td>
</tr>
</tbody>
&#13;