何时使用哪种控制器类型?

时间:2012-12-12 00:10:52

标签: ember.js

我似乎越来越多地对所出现的东西感到困惑,表面上至少是关于构建ember应用程序的相当基本的架构问题。

哪种控制器类型?

在过去一个月左右,我见过人们通过Ember.Controller,Ember.ArrayController,Ember.ObjectController和Ember.ArrayProxy实现控制器。删除ArrayController和ArrayProxy(由于它们相同),每种类型之间的常见用例是什么?

到目前为止,我已经能够收集到:

  • 当您要控制的视图中包含 n 元素时,应使用ArrayControllers / Proxies
  • 当视图足够简单以在单个对象中维护它的状态,或者是模型对象的单个实例时,应该使用ObjectControllers。
  • 控制器---?不知道。

控制器类型之间有哪些基本差异?似乎没有关于何时使用哪个以及哪个用例的具体信息。 API文档很好地告诉我每个人的细节,但不是什么时候使用它们。

视图和控制器之间的关系可能令人困惑

当通过路由ConnectOutlets函数调用连接View时,控制器和视图之间究竟发生了什么?

事件是否与视图本身相关(似乎就是这种情况),如果是这样,你在地球上与控制器单例进行交互以在其属性上执行CRUD-esq事物? this.get('controllerName')似乎没有做到这一点,几乎每个帖子或教程或代码示例都以不同的方式进行。

不是

的模型

我意识到Ember Data看起来有助于解决处理数据并使其保持同步的一些更令人恼火的部分,但从更大的角度来看,在“MVC”的概念中,ember似乎并没有任何形式的模型。它只是某个对象从特定的东西中获取子类,然后跟踪......某个地方?不知何故?神奇?

@trek足以说明Ember.Object可以管理ajax的数据并在客户端处理状态就好了,但是如果你看一下类似todomvc.com的ember应用程序,它会使用一个完全不同的localStorage范例然后执行我所看到的一切。

MVC方程的'模型'部分应该如何在这里完成?

意见让我想谋杀孩子

在向用户显示标记方面,似乎有很多方法可以构建“视图”。

  • ContainerViews,使用子视图/子视图
  • 嵌套网点
  • 把手模板+插座
  • 在控制器中使用#each foo
  • 通过文字注入(template: Ember.Handlebars.compile('<h1>foo</h1>')等)

考虑到这一点,使用ember构建模块化UI组件的“正确”方法是什么?对我来说,这对于采用这个框架来说,最重要的是痛点。

我喜欢Ember在网络上进行应用程序开发的方向。这些概念看起来很简单,但是详细程度是Objective-C(这是有道理的,因为它的谱系)但是我向上帝发誓我觉得我正在与那个该死的框架作斗争,而不是我实际上在处理我的应用程序。语法的冗长和API文档之外缺少结构化文档(面对它,300k的javascript是一大堆代码,可以抛出一些断点并尝试调试你的问题)。

我意识到你们面临的挑战,但希望这至少让你暂停一下,想想如何让那些与其他框架合作过的开发人员生活更轻松(或者甚至在内部工作)一个MVC框架,比如rails或django或backbone或angular)并说“这就是我们认为应该使用ember的方式”。

采取一些固执己见的软件设计决策并将其应用于社区。如果你这样做,我们什么也不会为你做啦啦队,保证。

1 个答案:

答案 0 :(得分:11)

请不要伤害任何孩子。 AFAIK的余烬核心团队都是18岁以上,所以任何与观看者有关的挫折感显然更好地针对成年人。考虑到这一点......

哪种控制器类型?

你已经得到了什么&#34;对,但也许错过了&#34;为什么&#34;。控制器可能有点误导,特别是来自铁轨。将这些控制器单例视为代表应用程序的状态(内存中)。

使用哪种控制器取决于应用程序部分所需的内容。例如,任何应用程序的餐巾纸草图可能都有topnav,postList,postDetails部分。在余烬中,每个都由一个或多个视图/控制器对表示。在这个应用程序中,我希望看到ApplicationController和NavigationController扩展Ember.Controler,而postList将扩展ArrayController,PostDetails将是一个ObjectController。

您可以使用Ember.Controller完成所有操作,但ObjectController和ArrayController对于包装模型数据非常有用。任何非平凡的余烬应用程序都可能会使用这三个。

视图和控制器之间的关系

控制器的工作是提供将在其中呈现视图的上下文。理想情况下,您希望保持逻辑不在视图中,因此典型的控制器将具有许多计算属性来执行以下操作:

  • 转换基础模型对象的数据
  • 排序/过滤/选择对象列表
  • 反映申请状态

与connectOutlets的交易是什么?这是您应该使用请求的路由/上下文来决定应将哪些视图/数据插入应用程序的出口。控制器的connectOutlet方法有一堆魔法让它变得简单,但可能太多魔法。当你打电话时会发生什么(afaik):parentcontroller.connectOutlet&#39; child&#39;是

  • Ember创建一个ChildView实例
  • parentController视图中的{{outlet}}句柄帮助器绑定到此childView实例
  • 使用router.childController单例作为其上下文
  • 呈现childView

在哪里做crud的东西?:通常在路由器上的动作中。起初这看起来很疯狂。可以认为ember路由器不像rails,而是作为一个刚刚处理路由的stateManager。在不久的将来,路由器API将改变以使其更加清晰。无论如何,使用路由器操作来执行诸如创建模型实例,提交/回滚事务和触发状态更改之类的操作。如果您对链接/按钮使用把手{{action}}帮助器,这很容易做到,因为它默认为路由器。

另一方面,视图应该具有“#34;对浏览器事件做出反应的逻辑”#34; - 这意味着真正的低级别的东西,如在鼠标悬停时显示/隐藏某些东西,或者与第三方库集成以进行效果和动画。

您可能会发现此截屏视频有助于了解如何执行CRUD-esq事情: http://blog.bigbinary.com/2012/09/06/crud-application-in-emberjs.html

模特WTF?

在Ember中同意,任何物体都可以用作“模型”。我认为@trek很好地演示了如何通过Ember.Object实现这一目标。这适用于一个简单的应用程序,六个月前可能是最好的选择,因为余烬数据真的不成熟。我不清楚ember的todomvc应用程序的历史,但肯定是几个月前写的。确定它应该更新,但同时我不建议使用它来了解当前的最佳实践。

相反,你应该使用余烬数据。在过去的几个月里,它已经真正发展,应该是任何新的,非平凡的余烬应用程序的默认选择。 @tomdale刚刚就这个主题发表了精彩的演讲,我建议看看:https://speakerdeck.com/tomdale/ember-data-internals

&#39;适当的&#39;使用ember构建模块化UI组件的方法

用于构建模块化UI组件:

  • ContainerViews,使用子视图/子视图
  • 通过文字注入(模板:Ember.Handlebars.compile ...)

建立个人申请:

  • 嵌套网点
  • 把手模板+插座
  • 在控制器中使用#each foo

构建模块化UI组件与构建应用程序完全不同。 Ember.View和它的子类是为此目的而设计的。您可以轻松地扩展/组合它们以使用自定义行为组合窗口小部件,并跨应用程序共享这些窗口小部件。

至少我是怎么看到它完成的。如果它们供内部使用,也可以引用把手模板而不是对象文字,但是如果计划分发对象文字方法似乎是最好的。

一个很棒的现实世界的例子是ember-bootstrap项目。通过阅读该项目的来源,我学到了很多关于使用余烬视图的知识。 http://emberjs-addons.github.com/ember-bootstrap/

<强> TLDR

  • 选择映射到所代表数据类型的控制器
  • 控制器为视图提供上下文并记住应用程序状态
  • 使用模型的ember数据
  • 使用Ember.View的子类来制作组件
  • 对孩子们好一点