【问题标题】:Ember: how to bind HTML class to Service property, so that class is dynamicEmber:如何将 HTML 类绑定到 Service 属性,使该类是动态的
【发布时间】:2019-01-30 16:10:23
【问题描述】:

我有一个家长route。在这个路由里面有一个组件被渲染。

route 有一个 template.hbs 文件,其中包含一个 HTML div 元素。我需要能够从我的孩子component 中更改此 div 元素的类。

为此,我计划使用一项服务。想法是将服务注入route 和子component,然后将 div 的类绑定到服务上的属性。然后,当我将服务注入子组件时,我可以更改属性并查看父路由反映的任何更改。

问题是,绑定似乎不起作用!

父路由:

模板: <div class={{model.containerClass}}>

Route.js:

dashboardContainerManager: service('dashboard-container-manager'),

afterModel(model) {
   model.set('containerClass', this.get('dashboardContainerManager').dashboardContainerClass);

服务:

export default Service.extend({
  dashboardContainerClass: null,

  init() {
    debugger; //placed to ensure one instance being made
    this._super(...arguments);
    this.set('dashboardContainerClass', 'container dashboard-container'); //need to set it here to prevent glimmer error
  },

  changeContainerClass(newClass) {
    debugger;
    this.set('dashboardContainerClass', newClass);
  }
});

子组件:

  dashboardContainerManager: service('dashboard-container-manager'),
  init() {
    this._super(...arguments);
    this.get('dashboardContainerManager').changeContainerClass('test');
  },

上述代码的结果是我的 div 的类最初设置为“容器仪表板容器”,因为这是我的服务上的 dashboardContainerClass 属性初始化的值。但是,当我的组件内的值更改为“test”时,我的 div 的类没有更新,这表明它没有正确绑定到 dashboardContainerClass 的值。我也尝试在不同的地方使用计算属性,但无法正常工作。

我在这里做错了什么?!

【问题讨论】:

    标签: javascript ember.js


    【解决方案1】:

    这里有一个 reads 计算属性宏可以帮助您:

    https://emberjs.com/api/ember/3.7/functions/@ember%2Fobject%2Fcomputed/reads

    在您的组件中,您只需执行以下操作:

    import { reads } from '@ember/object/computed';
    
      // ...
      dashboardContainerManager: service('dashboard-container-manager'),
    
      containerClass: reads('dashboardContainerManager.dashboardContainerClass'),
    

    更新/完整示例:

    服务:

    export default Service.extend({
      dashboardContainerClass: 'container dashboard-container',
    
      changeContainerClass(newClass) {
        this.set('dashboardContainerClass', newClass);
      }
    });
    

    路线:

    export default Route.extend({
      // removed afterModel and service injection
    });
    

    控制器:

    export default Controller.extend({
      containerManager: service('dashboard-container-manager'),
    
      containerClass: reads('containerManager.dashboardContainerClass'),
    });
    

    模板:

    <div class='some-other-class {{containerClass}}'>
      other stuff
    </div>
    

    【讨论】:

    • 谢谢,我试试看。你的意思是在我的 route.js 中(而不是在我的组件中)?
    • 啊!不,我的意思是在组件或控制器内部。路由的范围与模板范围不同。路由只是用于管理路由事件 / before/model/after 钩子,所以如果你想从路由对应的模板访问任何东西,它需要在控制器中指定。希望这会有所帮助!
    • 这就是为什么我一直在 afterModel() 方法内的模型上设置属性...以便可以从模板访问它。 - p.s 没用 x((((((
    • 好的,明白了。服务属性更新时模型不会更新,但计算属性会更新。模型仅在导航或路线参数更改时更新
    • 我将添加一些额外的代码来说明我如何在一秒钟内完成整个事情
    猜你喜欢
    • 2016-10-11
    • 1970-01-01
    • 2020-07-13
    • 2022-01-01
    • 1970-01-01
    • 2015-06-05
    • 1970-01-01
    • 2014-11-24
    • 2014-09-10
    相关资源
    最近更新 更多