从另一个组件Ember重新渲染一个组件

时间:2018-11-16 12:20:47

标签: javascript ember.js

我试图在单击另一个component时重新呈现特定的component。当用户单击特定的button component时,sessionStorage中的变量将更改,另一个component使用该变量来显示数据。单击后,我希望该特定组件重新呈现自己。我见过Ember Re-render componentEmber Rerendering component within component,但在我看来,它们似乎没有用。这是我的文件:

模板/组件/按钮/button-cancel.hbs

{{#each-in metaData as |module definition|}}
  {{#if (eq definition.name "cancel_button") }}
  <button class={{definition.css_class}} {{action "changeToAccounts"}}> Accounts </button>
  {{/if}}
{{/each-in}}
{{yield}}

组件/按钮/button-cancel.js

import Component from '@ember/component';
import MD from "../../utils/metadata";

export default Component.extend({
  init: function() {
    this._super(...arguments);
    this.metaData = MD.create().getMetaViewStuff("Leads", "record", "buttons");
    //    console.log(this.metaData);
  },
  actions: {
    changeToAccounts: function() {
      sessionStorage.setItem('module', "Accounts");
    }
  }

});

模板/组件/面板/list-panel.hbs

{{buttons/button-save}} <!--This button is same as button-cancel-->
{{buttons/button-cancel}}
{{field-list-headers}}
{{yield}}

components / field-list-headers (需要重新渲染的组件)

import Component from '@ember/component';
import MD from "../utils/metadata"

export default Component.extend({
  init: function(){
    this._super(...arguments);
    this.metaData = MD.create().getMetaViewStuff(sessionStorage.getItem('module'), "list", "panels")
  }
});

函数getMetaViewStuff

  getMetaViewStuff: function(module, submodule, item, i18n) {
    if (this.modules[module]["views"][submodule]["meta"] !== undefined && this.modules[module]["views"][submodule]["meta"][item] !== undefined) {
      let meta = this.modules[module]["views"][submodule]["meta"][item];
      return meta;
    }
    return false;
  }

1 个答案:

答案 0 :(得分:1)

我的建议是通过服务共享相同的属性,并使用该服务更新本地存储并在该服务上缓存值。我提供了一个example,它使用服务在两个组件之间共享值(我不能在旋转中使用本地存储)。

因此,假设我们要以表或有序列表的形式显示编程语言的列表。我们有两个组件,用于切换模式的可重用mode-changer按钮和用于实际呈现列表的programming-languages组件,它们都与共享的mode-service进行交互。:

export default Ember.Service.extend({
  init(){
    this._super(...arguments);
    //actually read from local storage here and set default on null
    this.set('mode', 'list');
  },
  toggleMode(){
    let newValue = this.get('mode') === 'list' ? 'table' : 'list';
    //actually store to local storage here before caching on the service
    this.set('mode', newValue);  
  }
});

想象一下该模板显示了两个组件:

{{programming-languages languages=languages}}
{{mode-changer}}

mode-changer注入mode-service,通过其导出逻辑按钮文本并通过mode-service切换mode的{​​{1}}属性:

toggleMode
export default Ember.Component.extend({ modeService: inject(), buttonText: computed('modeService.mode', function(){ let mode = this.get('modeService.mode'); return mode === 'list' ? "Change to table" : "Change to list"; }), actions: { toggleMode(){ let modeService = this.get('modeService'); modeService.toggleMode(); } } });

组成部分:

mode-changer

<button onclick={{action 'toggleMode'}}>{{buttonText}}</button> 组件通过计算属性将其渲染模式基于programming-languages

modeService.mode

以便对export default Ember.Component.extend({ modeService: inject(), renderList: computed('modeService.mode', function(){ let mode = this.get('modeService.mode'); return mode === 'list'; }) }); 进行更改将导致计算出的属性无效并触发组件的呈现。

modeService.mode

在Ember中,服务是单例的,因此这种共享在许多情况下是适当的。对我来说,这比任何其他实际存储/检索对组件本身的引用并调用其渲染功能的解决方案要好得多。