【问题标题】:rerender view when model property change in EmberJS当 EmberJS 中的模型属性更改时重新渲染视图
【发布时间】:2023-11-09 13:09:01
【问题描述】:

我正在尝试使用 EmberJS 和 HighchartJS 开发一个小型应用程序,但在 Model 属性更改后重新渲染 HighChartJS 时遇到了一些问题。这是http://www.loancomparison.com.s3-website-us-east-1.amazonaws.com/

App.Loan = DS.Model.extend({
    name : DS.attr('string'),
    principal : DS.attr('number'),
    interest_rate : DS.attr('number'),
    months_to_pay : DS.attr('number')
});

App.LoansView = Ember.View.extend({
    templateName: "loans",

    loansChanged: function() {
        //this.rerender();
        Ember.run.scheduleOnce('afterRender', this, 'propertyChanged');
    }.observes('controller.@each.principal', 'controller.@each.name', 'controller.@each.interest_rate', 'controller.@each.months_to_pay'),

    propertyChanged : function() {
       console.log("property changed");
       this.loadHighChart(); // This will load the highchart function.
    },
});

我想要的是在模型属性完成更改时通知视图。但是,在使用观察时,它会在模型​​开始更改时通知视图。这会导致 scheduleOnce 仅在模型属性更改的初始状态下运行。

编辑:已解决 解决方案非常简单,我只需要在模型贷款下创建一个“修改”的属性。然后,每当进行编辑时,我都会更新此模型。现在视图只需要观察这个“修改”属性的变化。

【问题讨论】:

  • 模型属性更改什么时候“完成”?
  • 我希望在用户完成编辑后将通知发送到视图。这也意味着模型属性完成了更改。
  • 当用户单击“保存”按钮时,为什么不直接运行更改后的函数?
  • +1 移除 loanChanged 方法,并将 this.loadHighChart() 添加到 save 操作 github.com/pmkhoa/loan-comparison/blob/master/source/assets/js/…

标签: ember.js highcharts


【解决方案1】:

你会想在你的LoanController 中加入保存actionhttps://github.com/pmkhoa/loan-comparison/blob/master/source/assets/js/app/controllers/loanController.js#L7

您可以使用Ember.Evented 在视图和控制器之间非常轻松地进行通信:

App.LoanController = Ember.ObjectController.extend(Ember.Evented, { <--PASS IN EMBER.EVENTED     
  //...
    save: function () {
      this.set('isEditing', false);
      this.get('model').save().then(function () {
        this.trigger('highChartReload'); 
      }.bind(this));
    },
  //...
});

请注意,我已将 Ember.Evented 传递到控制器中(就像您使用任何 mixin 一样...)并且我已将 trigger 添加到保存 action

现在,我们要在视图中监听该事件:https://github.com/pmkhoa/loan-comparison/blob/master/source/assets/js/app/views/loansView.js#L3

App.LoansView = Ember.View.extend({
  //...
  didInsertElement: function () {
    this.get('controller.controllers.loan').on('highChartReload', $.proxy(this.loadHighChart, this));
  },
  //...
});

现在视图将监听LoanController 以触发事件,然后触发loadHighChart 方法。

最后要做的就是告诉LoansControllerneed'贷款':

App.LoansController = Ember.ArrayController.extend({ 
  needs: ['loan'],
  //...
});

应该这样做。希望对您有所帮助!

【讨论】:

  • 我在我的应用中实现了这个,但是视图没有监听 LoanController 来触发 highChartReload 事件。 github.com/pmkhoa/loan-comparison/blob/master/source/assets/js/…
  • 嗯...尝试在didInsertElement 挂钩中添加断点或console.log 以检查this.get('controller.needs')this.get('controller').toString() 另外,控制台中是否有任何错误?
  • 另外,您是否看到此控制台日志的输出:github.com/pmkhoa/loan-comparison/blob/master/source/assets/js/…
  • 点击保存按钮后我可以看到“重新加载”日志。 this.get('controller.needs') & this.get('controller').toString() 的控制台日志是: - ["loan", nextObject: function ...] - 不知道为什么视图没有监听事件。
  • 嗯...我想它可能是触发发生在一个动作中。查看我更新的编辑。