2

我有一个与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;
  };
}

这样,我可以根据需要生成bounceProtection对象来保护多个密钥,即使是js的异步特性。

var myKeyBP = new BounceProtection();
4

3 回答 3

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;
    });
  });
});
于 2013-07-17T13:17:56.237 回答
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);
于 2013-07-17T13:29:09.060 回答
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;
  });
})
于 2015-11-05T13:40:38.157 回答