首页 文章

使用ember-cli-mirage失败的Ember destroyRecord(或deleteRecord然后保存)

提问于
浏览
2

我想要做的是将ember-cli-mirage整合到这个todo应用程序中,https://github.com/ember-cli/ember-cli-todos . 此应用程序使用Ember 2.0或更高版本 . 设置:

  • 克隆todo应用程序,然后cd进入app目录 .

  • shell> npm install

  • shell> bower安装

  • shell> ember serve

我确认该应用程序正在宣传(除了一个与此无关的小问题) . 我可以创建,更新和删除待办事项 . todo应用程序使用ember-data-fixture-adapter / FIXTURES为应用程序提供数据 .

我整合ember-cli-mirage的步骤是:

  • 注释app / models / todo.js中的Todo.reopenClass块(创建FIXTURES /种子数据的代码) .

  • 删除了app / adapters目录(仅包含一个文件application.js(仅包含一行,"export from 'ember-data-fixture-adapter';")) . 我很确定这整个目录只适用于FIXTURES设置 .

  • shell> ember install ember-cli-mirage

  • 按照http://www.ember-cli-mirage.com/docs/v0.1.x/working-with-json-api/的说明设置ember-cli-mirage部件(app / mirage / {config.js,factories / post.js,scenarios / default.js}) .

我会发布app / mirage / {config.js,factories / post.js,scenarios / default.js}的代码,如果有人需要看到它,但它基本上只是ember-cli-mirage中指令的副本页面(“用户”型号名称替换为“post”) .

我重新启动了ember服务器 . 除了删除待办事项外,一切正常 . 通过按下将指针移动到待办事项右侧时出现的“x”按钮来完成记录删除 . 我发现它在删除记录的save()部分失败了 . 删除记录的代码(使用“x”按钮界面)位于app / components / todo-item / component.js中,它看起来像这样:

removeTodo() {
  var todo = this.get('todo');

  todo.deleteRecord();
  todo.save();
}

当我尝试删除todo项时,浏览器控制台打印“Successful request:DELETE / todos / n”(“n”是todo id),然后它会打印出一个神秘的错误消息以及堆栈跟踪 .

我注释掉了“todo.save();”上面的一行 . 当我删除todo项目时,删除仍然失败,但在控制台上,在“成功请求:DELETE / todos / n”消息之后不再有错误消息 .

所以我更改了上面的removeTodo代码,试图让错误消息更加清晰 . 我改成了这个:

todo.save().then(function() {
    console.log('Save OK.');
  }).catch((err) => {
    console.log('Save failed.');
    console.log(err.message);
});

我已经尝试过对这里和那里的各种更改,但始终出现的错误消息是:

断言失败:适配器无法为已具有id的记录分配新ID . 有id:3,你试图用undefined更新它 . 这可能是因为您的服务器返回数据以响应与您发送的ID不同的查找或更新 .

我看到一条错误消息,上面写着“normalizeserializer ...”文本,但我忘了复制整条消息 .

我添加了一个适配器:

shell> ember g adapter application

// app/adapters/application.js
import DS from 'ember-data';

export default DS.JSONAPIAdapter.extend({
});

但这并没有解决它 .

BTW,一个todo项目创建,也可以调用保存todo项目,工作 . 代码驻留在app / components / todos-route / component.js中:

createTodo() {
  const store = this.get('store');

  // Get the todo title set by the "New Todo" text field
  var title = this.get('newTitle');

  if (title && !title.trim()) {
    this.set('newTitle', '');
    return;
  }

  // Create the new Todo model
  var todo = store.createRecord('todo', {
    title: title
  });

  // Clear the "New Todo" text field
  this.set('newTitle', '');

  // Save the new model
  todo.save();
}

1 回答

  • 4

    你的Mirage嘲笑 DELETE/todos/:id 是什么样的?看起来您正在使用包含 id 的JSON有效内容来响应DELETE请求,这会导致问题 .

    相反,你可以尝试一些返回空响应体的东西,比如

    this.del('/todos/:id', (db, request) => {
      let id = request.params.id;
      db.todos.remove(id);
    
      return new Mirage.Response(204, {}, {});
    });
    

    (这段代码未经测试,但希望你能得到这个想法) .

    另一个小点,模型上有一个 destroyRecord 方法,它基本上同时执行 deleteRecordsave .

相关问题