【问题标题】:Index view not refreshing after receiving updated data from backend从后端接收更新数据后索引视图不刷新
【发布时间】:2013-08-13 13:37:13
【问题描述】:

我正在测试我的应用程序,所以我正在执行以下操作:

  1. 我显示了一个索引视图 (#/locators/index),其中包含 Locator 对象,我最初使用 App.Locator.find(); 加载它
  2. 我手动修改后端
  3. 手动(使用按钮/操作)我触发了 ember 前端中数据的刷新,而不更改路由。我用App.Locator.find().then(function(recordArray) {recordArray.update();}); 做到这一点。我通过控制台日志看到一个列表请求被发送到后端,并且收到了最新数据。我假设这是用来更新商店的。
  4. 但是:视图不会自行更新以显示这些新数据

为什么当商店收到新数据时视图没有自动更新?这不就是 Ember 中数据绑定的重点吗?

如果我现在执行以下操作:

  1. 打开任何其他路线
  2. 返回定位器索引路线 (#/locators/index)
  3. Ember 发送新请求以列出定位器
  4. 显示索引视图,其中包含正确的数据(因为它已经在商店中了?)
  5. 收到新数据

(我不能 100% 确定 4 和 5 会按此顺序发生,但我很确定)

因此,我的印象是数据在商店中已正确更新,但不知何故需要对视图进行完全重新渲染才能显示这些新数据,例如通过离开和重新进入路线。这是真的?我可以以编程方式强制重新渲染吗?

【问题讨论】:

    标签: ember.js ember-data


    【解决方案1】:

    当底层模型被控制器更改时,Ember 会更改视图数据(绑定到视图)

    (仅当应用程序的状态改变(url改变)路由器钩子被调用) 当您通过捕获视图触发的操作在您的路线内执行this.refesh() 时,您的问题可能会得到解决。

    App.IndexRoute = Ember.Route.extend({
        actions: {
            dataChanged: function() {
                this.refresh();
            }
           },
           //rest of your code goes here
    
            });
    

    为了让你修改数据的车把模板工作,应该有一个名为 dataChanged 的​​操作

    示例:

    假设这个动作负责改变/修改/删除底层数据

    <button {{action 'dataChanged'}}> Change Data </button>
    

    Refresh 方法实际上是进行模型刷新并将其传递给相应的控制器,该控制器确实改变了视图。

    【讨论】:

      【解决方案2】:

      您可以尝试以下几件事:

      如果您在 ArrayController 内部,则强制将内容替换为新数据:

      this.replaceContent(0, recordArray.get('length'), recordArray);
      

      或者尝试在每条记录通过循环记录数组时调用reload

      App.Locator.find().then(function(recordArray) {
        recordArray.forEach(function(index, record) {
          record.reload();
        }
      }
      

      如果第二种方法有效,您还可以覆盖模型类中的 didLoad 钩子,而不必一个一个地循环它们:

      App.Locator = DS.Model.extend({
        ...
        didLoad: function(){
          this.reload();
        }
      });
      

      如果这可行并且您需要在更多模型类中使用此行为,请考虑创建一个通用 mixin 以在更多模型类中使用:

      App.AutoReloadMixin = Ember.Mixin.create({
        didLoad: function() {
          this._super();
          this.reload();
        }
      });
      
      App.Locator = DS.Model.extend(App.AutoReloadMixin, {
        ...
      });
      
      App.Phone = DS.Model.extend(App.AutoReloadMixin, {
        ...
      });
      

      根据您的回答进行更新

      Handlebars.registerHelper 无法识别绑定,我确定这会导致您的绑定无法触发。您应该使用 Handlebars.registerBoundHelper 或简单地使用 Handlebars.helper,这是等效的:

      Handlebars.helper('grayOutIfUndef', function(property, txt_if_not_def) {
        ...
      });
      

      希望这会有所帮助。

      【讨论】:

      • 感谢您的详细回复。目前我的印象是,问题是由于在索引视图中我使用定制的车把助手显示了一些属性,这可能是我实现它的方式阻止了属性的绑定无缝工作.我正在重新实现一些带有视图的助手,这些视图很容易正确实现,而不会破坏“属性传输链”。目前,结果令人鼓舞。万一我碰壁了,我会试试你的建议。
      • 这是有道理的。您是否有指向 Ember 中不同 Handlebars 扩展的文档的链接?
      【解决方案3】:

      这似乎是因为我使用了自定义车把助手,如下所示:

      Handlebars.registerHelper('grayOutIfUndef', function(property, txt_if_not_def) {
          // HANDLEBARS passes a context object in txt_if_not_def if we do not give a default value
          if (typeof txt_if_not_def !== 'string') { txt_if_not_def = DEFAULT_UNDEFINED_STR; }
          // If property is not defined, we return the grayed out txt_if_not_def
          var value = Ember.Handlebars.get(this, property);
          if (!value) { value = App.grayOut(txt_if_not_def); }
          return new Handlebars.SafeString(value);
      });
      

      我一直是这样使用的:

      {{grayOutIfUndef      formattedStartnode}
      

      现在我已经移动到一个视图:

      {{view App.NodeIconView nodeIdBinding="outputs.startnode"}}
      

      具体实现如下:

      App.NodeIconView = Ember.View.extend({
          render: function(buffer) {
              var nodeId = this.get('nodeId'), node, html;
              if (nodeId) {
                  node = App.getNode(nodeId);
              }
              if (node) {
                  html = App.formattedLabel.call(node, true);
              } else {
                  html = App.grayOut(UNDEFINED_NODE_NAME);
              }
              return buffer.push(html);
          }
      });
      

      我不知道为什么,但似乎使用自定义车把助手破坏了属性绑定机制(也许我的实现是错误的)

      【讨论】:

      • Handlebars.registerHelper 没有绑定意识,请参阅我的答案的编辑了解更多信息
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-07
      • 1970-01-01
      • 2016-05-03
      • 2017-11-11
      • 1970-01-01
      • 1970-01-01
      • 2020-12-17
      相关资源
      最近更新 更多