【问题标题】:How to make an action affect a sibling view without controller.get('view')?如何在没有 controller.get('view') 的情况下使操作影响同级视图?
【发布时间】:2013-01-30 19:07:10
【问题描述】:

快速上下文: 应用程序视图有 2 个出口。一个用于工具栏。另一个用于可路由的“主”视图层次结构。

app -- main
   \-- toolbar

我需要工具栏中的一些按钮来触发“主”视图中的事件。不更新任何模型中的任何数据。我只是指示它触发对视图呈现的绘图库的一些更改。清除画布,重置缩放值等。

在 1.0 pre2 和更早的版本中,我使用了操作和 router.get('someController.view') 来访问我想要的视图并触发操作/方法/事件。算不上应用程序设计的巅峰之作,但运行良好。

这个选项现在已经消失了,我对 good 的选择感到茫然。 在不在子/父层次结构中的视图之间进行通信时,我应该使用什么机制?我想出的一切都是笨拙的,并且触发了我的感觉,“Ember 有更好的方式”。

总之我想要:

  • 用于触发事件的工具栏按钮
  • 对此作出反应并对其自身部分执行一些更新的主视图。
  • 主视图不会像通过路由那样在 Ember 意义上重新渲染。它使用绘图库并将其所有属性和行为集成到 Ember 模型和控制器中不会很有趣。
  • 工具栏和主视图共享一个父视图,但位于不同的“分支”上。

我正在考虑的糟糕选择:

工具栏在很大程度上是一个应用程序级别的问题,但它确实有一些需要指示特定视图的按钮。我在 Ember 中看到的一个选项是将工具栏嵌套在“主”视图下。这对于它的其他一些功能来说似乎是错误的。

通信可以由一个控制器(甚至可能是一个模型)来处理,该控制器将保存工具栏设置的属性,“监听”视图会对其做出反应并重置其值。这听起来像是对控制器和模型目的的滥用,并且像是一个非常糟糕的事件监听器设置。

我可以将绘图库作为 App.Drawing 之类的全局应用程序,但这似乎也很糟糕。这也意味着操作仍然无法使用视图中的任何数据来更新绘图库。

有什么建议吗?

【问题讨论】:

    标签: ember.js ember-router


    【解决方案1】:

    在不在子/父层次结构中的视图之间进行通信时应该使用什么机制?

    在典型的 ember 应用程序中,这种通信应该发生在控制器之间。否则“糟糕的选项2”就在正确的轨道上:

    通信可以由一个控制器(甚至可能是一个模型)来处理,该控制器将保存工具栏设置的属性,并且“监听”视图会对其做出反应并重置其值。

    考虑使用两个控制器。工具栏操作将针对ToolbarController,它负责维护工具栏的状态并更改主以响应用户操作。 ToolbarController 应该通过 needs 属性声明对 MainController 的依赖。例如:

    App.ToolbarController = Ember.Controller.extend({
      needs: ['main'],
      buttonOneGotAllPressed: function() {
        main = this.get('controllers.main');
        main.turnOffAnOption();
        main.makeSomeOtherChange();
      }
    }); 
    

    现在MainController 可以专注于 MainView 的状态。它不应该知道ToolbarController 或它的按钮。

    这听起来像是对控制器和模型目的的滥用,并且像是一个非常糟糕的事件监听器设置。

    同意这可能是对模型目的的滥用,但这正是控制器的用途。

    这绝对不是事件侦听器设置,但这似乎不适合您的情况。您描述的工具栏似乎只存在与主视图交互,因此拥有一个依赖于主视图并直接与其交互的工具栏控制器是有意义的。

    如果组件真正解耦,那么观察者 (Pub/Sub) 模式可能更合适。如果感兴趣,请参阅How to fire an event to Ember from another framework

    【讨论】:

    • 这是一些严肃的魔法。我在文档中看不到使用“需要”属性的任何参考。 Ember 充满了隐藏的惊喜,我不确定这是否是一件好事。极难获得整个框架的心智模型。最令人沮丧的是,没有明确定义类的职责。
    • 同意,这是一个非常有趣的功能。如果我在主视图中更改某些状态,我会立即这样做。这自然可以由控制器上的属性控制。但是,当我想在视图上触发的东西更类似于“闪烁”、“弹跳”之类的东西时,我觉得将它与属性联系起来不太舒服。例如。这将是一个名为“is_bouncing”的属性,控制器将更改为 true,并且视图在看到它为 true 时立即重置为 false。它们基本上是用作触发器而不是表示任何状态的布尔值。
    • 在此处添加注释以供将来参考:现在已记录在 emberjs.com/guides/controllers/dependencies-between-controllers
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    • 2022-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多