我有一个文本区域,我正在与GoInstant同步。这是代码的样子:
var myRoom = platform.room('myRoom');
var myKey = myRoom('myKey');
// Listen to set events on the platform key and update a textarea
myKey.on('set', function(textAreaContent) {
$('textarea').val(textAreaContent);
});
// When the textarea changes, set the platform key
$('textarea').on('change', function(){
var textAreaContent = $(this).val();
myKey.set(textAreaContent, function(err) {
if (err) throw err;
});
})
这会创建一个无限循环,当更新一个文本字段时,即当更改textarea的值时,这会触发平台密钥更新,从而无限地更改textarea的值...
编辑:基于最佳答案,我想出了以下构造函数:function BounceProtection() {
var remoteUpdate = false; // remote toggle
this.local = function(cb) {
if (remoteUpdate) return;
cb();
};
this.remote = function(cb) {
remoteUpdate = true;
cb();
remoteUpdate = false;
};
}
这样,即使js具有异步性,我也可以根据需要生成bounceProtection对象以保护多个键。
var myKeyBP = new BounceProtection();
答案 0 :(得分:5)
防止无限传播循环的快速方法:
// Infinite loop prevention
var bounceProtection = {
remoteUpdate: false, // remote toggle
local: function(cb) {
if (this.remoteUpdate) return;
cb();
},
remote: function(cb) {
this.remoteUpdate = true;
cb();
this.remoteUpdate = false;
}
};
var myRoom = platform.room('myRoom');
var myKey = myRoom.key('myKey');
myKey.on('set', function(textAreaContent) {
bounceProtection.local(function() {
$('textarea').val(textAreaContent);
});
});
$('textarea').on('change', function(){
var textAreaContent = $(this).val();
bounceProtection.remote(function() {
myKey.set(textAreaContent, function(err) {
if (err) throw err;
});
});
});
答案 1 :(得分:1)
在编辑textarea之前,只需删除侦听器然后重新应用它(我也为您缓存了textarea,因此您不会在每个触发的事件上搜索DOM)。
我还建议你给textarea一个ID属性,因为看起来你正在使用一个textarea,但做一个标签搜索效率很低,很容易通过在页面上添加另一个textarea来解决。
var myRoom = platform.room('myRoom');
var myKey = myRoom('myKey');
var $textarea = $('textarea');
function setKey() {
var textAreaContent = $(this).val();
myKey.set(textAreaContent, function(err) {
if (err) throw err;
});
}
// Listen to set events on the platform key and update a textarea
myKey.on('set', function(textAreaContent) {
$textarea.off('change', setKey); // Remove listener
$textarea.val(textAreaContent);
$textarea.on('change', setKey); // Reapply listener
});
// When the textarea changes, set the platform key
$textarea.on('change', setKey);
答案 2 :(得分:0)
另一种可能的方法是在设置值之前先比较值。在事件没有可比较的值的情况下,可以说是不够通用,但在这种情况下,这个解决方案可行。
myKey.on('set', function(textAreaContent) {
var $textarea = $('textarea');
if ($textarea.val() !== textAreaContent) { // compare values first
$textarea.val(textAreaContent);
}
});
// When the textarea changes, set the platform key
$('textarea').on('change', function(){
var textAreaContent = $(this).val();
myKey.set(textAreaContent, function(err) {
if (err) throw err;
});
})