【问题标题】:Ember localstorage adapter has different data when I refresh当我刷新时,Ember localstorage 适配器有不同的数据
【发布时间】:2017-06-24 11:19:06
【问题描述】:

我对 Ember 比较陌生,一直在努力构建一个简单的 CRUD 应用以用于学习目的。我正在使用 localstorage-adapter 来模拟后端。由于 Ember Inspector 在不同的页面上显示不同的数据,我的调试非常糟糕。

现在我拥有完整的 CRUD 功能,除了更新。假设我创建了一首新歌曲 (S1),它是专辑 (A1) 的一部分。我可以将 S1 更改为属于另一个相册 (A2),即使我刷新它也会保存并保留在本地存储中。

现在,如果我决定要将 S1 的相册改回 A1,它将保存并显示在显示页面上,但如果我刷新,相册将恢复为 A2。如果我去编辑页面,S1的专辑被列为A2。如果我在编辑页面上刷新,它会更改为 A1,但即使我单击保存,它也会在显示页面上显示 A1,但如果我刷新或返回编辑,它会返回 A2...我觉得这特别奇怪因为它确实在初始编辑尝试时正确保存(并在页面重新加载时持续存在)。无法正确保存是后续的编辑尝试。

一首歌有一个标题并且属于一个专辑。

歌曲控制器

import Ember from 'ember';

export default Ember.Controller.extend({
  actions: {
    updateValue(value) {
      this.set('model.song.newAlbum', value)
    },
    updateSong(model) {
      this.store.findRecord('song', model.get('id'))
        .then(song => {
          if (song.get('newAlbum')) {
            this.store.findRecord('album', song.get('newAlbum'))
              .then(album => {
                song.set('album', album);
                album.save();
              })
          }
        song.save();
      })
      .then(() => this.transitionToRoute('songs.show', model.get('id')));
    }
  }
});

【问题讨论】:

  • 进一步说明问题:当我在不同的页面上刷新时,数据会发生变化。如果我去我的主页并清空缓存+硬重新加载,数据看起来是正确的。 S1 属于 A1。如果我然后导航到 S1 的编辑页面或 A2 的显示页面,数据会更改并且 S1 现在属于 A2。这导致我的应用程序出现许多其他问题。例如,如果我移动一些东西然后删除,在某个时候,某个页面会中断,因为它试图为不存在的东西获取数据记录(并且它应该不再与之有关系)。
  • 如果您使用 catch() 将错误处理程序添加到您的 save() 调用中,它会显示更多信息吗? guides.emberjs.com/v2.13.0/models/…
  • 我在控制台中添加了一个catch。记录错误,但没有记录任何内容。

标签: ember.js local-storage ember-data


【解决方案1】:

为确保数据在后端(即本项目中的本地存储)正确保存,您需要对关系进行更多管理。

您需要:

  1. 设置新专辑作为歌曲的专辑属性 - song.set('album', newAlbum)
  2. 保存歌曲的旧专辑(如果有从 oldAlbum.songs 删除歌曲的专辑)
  3. 保存歌曲:将song.album 属性持久化到后端
  4. 保存歌曲的新专辑:将更新后的newAlbum.songs 持久化到后端

此外,我使用了RSVP Hash to return multiple models,因此您不必在函数中获取歌曲数据对象(已解析并为您传递给模型)

import Ember from 'ember';

export default Ember.Route.extend({
  model(params) {
    return Ember.RSVP.hash({
      song: this.store.findRecord('song', params.song_id),
      albums: this.store.findAll('album')
    })
  },
  actions: {
    updateSong(song) {
      if (song.get('newAlbum')) {
        //  Get the current album's Ember object as 'oldAlbum'
        song.get('album').then((oldAlbum) => {
          // Then get the new album's Ember object as 'newAlbum'
          this.store.findRecord('album', song.get('newAlbum')).then(newAlbum => {
            // Set the song's album to the new album
            song.set('album', newAlbum);
            if (oldAlbum) {
              // Save the old album if it exists
              oldAlbum.save();
            }
            // Save the new album
            newAlbum.save();
            // Save the song
            song.save().then(() => {
              // Then transition to new route
              this.transitionTo('songs.show', song.get('id'))
            })
          })
        });
      }
    }
  }
});

最后,请注意,在您的 routes/application.js 中设置初始实体的推送仅推送到缓存而不是本地存储。有了这些,您将始终看到 Go Go Go 与 What Is Life 相关联——不要让它让您失望。

另外,请记住,您可以从开发人员工具中剪切和粘贴本地存储内容,以帮助调试其中的内容与 Ember 缓存。

【讨论】:

  • 当我将函数更改为看起来像您的函数并尝试进行编辑时,我收到一条错误消息“错误:断言失败:找不到路由 ag4g9”,其中 ag4g9 是我正在编辑的歌曲。由于某种原因,艺术家被删除了?它似乎仍然存在于本地存储中,但不存在于 Ember Inspector 中的数据中(取决于页面)。非常感谢您的帮助!
  • 在我看来,这可能是路由转换的问题,但如果没有看到更多代码或运行一个有效的最小示例,很难说是什么。你有机会在 github 上发布你的项目吗?
  • 是的,当然。我实际上是把它作为一个编码挑战来解决的,并且已经提交了它。也就是说,它不能正常工作的事实让我发疯了,我仍然想根据自己的知识弄清楚我做错了什么。 github.com/amygbui/ember
  • 非常感谢您发布 github 链接!我能够让项目运行并找到问题所在。总之,我们需要保存除了歌曲之外的专辑模型,以保持它们的“歌曲”属性并保持所有内容同步。
  • 非常感谢!这成功了,而且很有意义:D
猜你喜欢
  • 2015-02-18
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 2016-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多