从另一个组件重新渲染一个组件 Ember
Re render a component from another component Ember
我正在尝试在单击另一个 component
时重新呈现特定的 component
。当用户单击特定的 button component
时,sessionStorage
中的一个变量发生变化,另一个 component
使用它来显示数据。单击后,我希望该特定组件重新呈现自身。我已经看到 and Ember Rerendering component within component,但它们似乎不适用于我的情况。这是我的文件:
templates/components/buttons/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}}
components/buttons/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");
}
}
});
templates/components/panels/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;
}
我的建议是通过服务共享相同的 属性 并使用此服务更新本地存储并缓存所述服务上的值。我提供了一个 example,它使用一个服务在两个组件之间共享一个值(我不能在转动中使用本地存储)。
因此,假设我们想要以 table 或有序列表的形式显示编程语言列表。我们有两个组件,用于切换模式的可重用 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
属性 23=]:
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
的更改将导致计算的 属性 无效并触发组件的渲染。
{{#if renderList}}
<ol>
{{#each languages as |language|}}
<li>{{language}}</li>
{{/each}}
</ol>
{{else}}
<table>
<th>Language</th>
{{#each languages as |language|}}
<tr>{{language}}</tr>
{{/each}}
</table>
{{/if}}
在Ember中,服务是单例的,所以在很多情况下这样的共享是合适的。对我来说,这比实际上 stores/retrieves 引用组件本身并调用其渲染函数的任何其他解决方案要好得多。
我正在尝试在单击另一个 component
时重新呈现特定的 component
。当用户单击特定的 button component
时,sessionStorage
中的一个变量发生变化,另一个 component
使用它来显示数据。单击后,我希望该特定组件重新呈现自身。我已经看到
templates/components/buttons/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}}
components/buttons/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");
}
}
});
templates/components/panels/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;
}
我的建议是通过服务共享相同的 属性 并使用此服务更新本地存储并缓存所述服务上的值。我提供了一个 example,它使用一个服务在两个组件之间共享一个值(我不能在转动中使用本地存储)。
因此,假设我们想要以 table 或有序列表的形式显示编程语言列表。我们有两个组件,用于切换模式的可重用 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
属性 23=]:
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
的更改将导致计算的 属性 无效并触发组件的渲染。
{{#if renderList}}
<ol>
{{#each languages as |language|}}
<li>{{language}}</li>
{{/each}}
</ol>
{{else}}
<table>
<th>Language</th>
{{#each languages as |language|}}
<tr>{{language}}</tr>
{{/each}}
</table>
{{/if}}
在Ember中,服务是单例的,所以在很多情况下这样的共享是合适的。对我来说,这比实际上 stores/retrieves 引用组件本身并调用其渲染函数的任何其他解决方案要好得多。