EmberJS:如何从控制器调用组件函数并计算组件数据

EmberJS: How to call a component function from a controller and calculate the component data

我创建了一条路由,比如说日志(pods 结构),我创建了 controller.js、route.js 和 template.hbs

在模板中我初始化了一个网格组件。我也在开发自定义分页组件。

当我初始化网格组件时,我将数据作为属性,这些数据在从分页更改页面后会发生变化,我还想计算页面大小,网格容器中适合多少行。通过 pageSize 我可以计算出总页数。

我在网格组件中有计算 pageSize 的功能,但我想在我的 controller.js 中使用该数字。我通过发送操作来做到这一点,并且我已经成功地在我的控制器上输入了号码。

然后在 dataHandler computed 属性 我想计算网格将显示的数据。我收到了弃用错误,并且网格中也没有显示任何内容:

弃用:在 didInsertElement 挂钩中修改了 属性。你永远不应该在 didInsertElement 期间更改组件、服务或模型的属性,因为它会导致性能显着下降。 [弃用 ID:ember-views.dispatching-modify-属性]

这种情况可能吗?如果是,最好的方法是什么?

在我的代码下面:

logs/controller.js

export default Ember.Controller.extend({
  dataHandler: Ember.computed('pageSize', {
    set(key, value) {
      if (value) {
        this.set('pageSize', value);
      } else {
        this.set('pageSize', null);
      }
      return value;
    },
    get() {
      let data = this.get('data');
      if (!data) {
        let pageSize = this.get('pageSize');
        data = this._data(); //Here will calculate the data and pass them to component
        this.set('data', data);
      }
      return data;
    }
  }),
  actions: {
    setPageSizeFromDataGrid(pageSize) {
      this.set('dataHandler', pageSize);
    }
  }
});

logs/template.hbs

<div class='row'>
  <div class='col-md-12'>
    <h1>Request Logs</h1>
    {{#si-data-grid data=dataHandler rowHeight=35 pageSize="setPageSizeFromDataGrid"}}
      //some content
    {{/si-data-grid}}
  </div>
</div>

我的component.js

export default Ember.Component.extend({
  didRender() {
    let that = this;
    that._calculateContainerHeight();

    let children = that.childViews;
    let rowHeight = that.rowHeight || 20;

    let data = that.data;

    let columns = that._parseColumns(children);
    let pageSize = that.getPageSize(rowHeight);

    that.sendAction('pageSize', pageSize);

    Ember.$(that.get('element')).find('div#si-data-grid').kendoGrid({
      columns: columns,
      dataSource: new kendo.data.DataSource({
        data: data
      })
    });

    Ember.$(that.get('element')).find('div#si-data-grid tr').css('height', rowHeight);

 },
 getPageSize(rowHeight) {
   let paginationHeight = 40;
   let gridHeaderHeight = this.$().offsetParent().offset().top;
   let height = this.$().height() - gridHeaderHeight - paginationHeight;
   return Math.floor(height / rowHeight);
 }
});

我设法找到了解决问题的方法。

在我的 component.js 中,我添加了 didInsertElement 并安排 afterRender 发送操作

export default Ember.Component.extend({
  didInsertElement() {
    Ember.run.scheduleOnce('afterRender', this, '_updateChildViews');
  },
  didRender() {
    //some code
  },
  _updateChildViews() {
    let that = this;
    let rowHeight = that.rowHeight;
    let pageSize = that._getPageSize(rowHeight);
    this.sendAction('updateData', pageSize);
  }
});

在 logs/template.hbs

<div class='row'>
  <div class='col-md-12'>
    <h1>Request Logs</h1>
    {{#si-data-grid data=dataHandler rowHeight=35 updateData='updateData'}}
        //some code
    {{/si-data-grid}}
  </div>
</div>

和我的 logs/controller.js

export default Ember.Controller.extend({
  dataHandler: Ember.computed('pageSize', {
    set(key, value) {
      if (value) {
        this.set('data', this._data());  //calculate the data to be shown on the data grid component      
      } else {
        this.set('data', []);
      }
      return this.get('data');
    },
    get() {
      let data = this.get('data');
      if (!data) {
        this.set('data', []);
      }
      return data;
    }
  }),
  actions: {
    updateData(pageSize) {
      this.set('dataHandler', pageSize);
    }
  }
});