javascript - Ember 自动保存 - 排队保存请求

标签 javascript ember.js ember-data ember-cli

例如,用户在文本框内不断按下某个键,并向服务器发送保存请求以保存该值。

通过去抖动来推迟后续事件是行不通的,因为每个 keyUp 都在一个新的运行循环中运行,这与长时间按住按键并以这种方式输入字符不同。

所以问题是:什么是最符合 Ember Way 的方法 A) 在发送新请求之前等待请求完成,以确保旧值不会覆盖新值,以及 B) 确保至少发送最后一个请求,保存最新的用户输入值。

更新:

在四处寻找之后,似乎我最初错过了一件重要的事情,这导致每次按下键时我的保存都运行,而不是每个去抖周期一次,是函数传递到去抖方法必须命名。分解出保存代码并将引用传递给函数,这样就可以在 2 秒的间隔内最多保存一次。

  keyUp: function(e) {
    Ember.run.debounce(this, this.saveFieldValue, 2000);
  },
    
  saveFieldValue: function() {
    const field = this.get('field');
    field.save();
  },

UPDATE2:@nem035 下面的回答解决了我的其他要求:排队保存,因此不会丢失任何内容。去抖动有效,但不能保证。

最佳答案

如果您不关心事件被忽略,您的事件去抖动方法是最 Ember 的方法,并且可能是最适合您的方法,但这里有一些可能的替代方法:

简单方法(忽略额外事件)

你可以做的一件简单的事情就是有一个标志,初始化为 false,在操作开始之前设置为 true 并重置回 false 当操作完成时。

saveFieldValue: function() {
  if (!this.get('isSaving')) {

    const field = this.get('field');

    this.set('isSaving', true);
    field.save().then(() => {
      this.set('isSaving', false);
    });
  }
}

这类似于您的去抖动方法(额外的事件被忽略),但我们有一个标志,如果先前的操作尚未完成,则可以防止操作发生。拥有一个标志还可以帮助您在保存数据时显示微调器或禁用在保存期间无法使用的按钮或类似的东西。


复杂的方法(额外的事件排队)

如果您不希望在保存数据时吞噬/忽略任何事件,而是希望所有事件都发生(最终),您可以做的另一件事是创建自己的事件队列来处理这是通过排队保存事件并按顺序运行它们,一个接一个。

此外,您还必须处理队列在一段时间后重新检查自身以运行可能同时排队的任何任务的情况。

这是一个使用数组作为队列的简单演示:

// ...

queue: null,

init() {
  this._super(...arguments);

  // ...

  // initialize a new queue for each instance
  this.set('queue', Ember.A()); 

  // start the queue process
  this.processQueue();
},

processQueue() {
  const queue = this.get('queue');

  // if the queue is empty, try again in 100ms (this value is arbitrary, see what would work best for you)
  if (Ember.isEmpty(queue)) {
    Ember.run.later(this, this.processQueue, 100);
  } 

  // otherwise remove the oldest field
  // save it
  // and then re-run the queue process
  else {
    // remove and save the oldest-first
    queue.shiftObject().save()
      .then(() => {
        // here we can do success handling for the saved field
      }, () => {
        // here we can do error handling for the saved field
      })
      .then(() => {
        this.processQueue();
      });
  }
},

saveFieldValue: function() {
  const {
    field, queue
  } = this.getProperties('field', 'queue');

  // push the current field value to the queue 
  queue.pushObject(field);
}

这是一个 EmberTwiddle例子

关于javascript - Ember 自动保存 - 排队保存请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39109443/

相关文章:

javascript - Ember 数据: createObject with an initial async relationship value

javascript - 如何在 ember.js 中创建一个寄存器?存储.createRecord

ember.js - 合并 route 的两个模型数组

javascript - 有没有办法使用JavaScript和HTML显示当前的用户名?

javascript - 有没有办法将变量从 javascript 导入到 sass,反之亦然?

javascript - 在 JSON 对象的顶部添加一些东西

html - Ember.js 浏览器支持吗?

ember.js - 使用 ember.js 无限滚动(延迟加载)

javascript - Style.backgroundColor 或 style.background 没有执行它的功能

javascript - Ember JS : How can a parent route/controller observe its child route/controller changing?