【问题标题】:When to use which controller type?何时使用哪种控制器类型?
【发布时间】:2012-11-29 14:56:13
【问题描述】:

我似乎越来越困惑,表面上至少是关于构建 ember 应用程序的非常基本的架构问题。

哪种控制器类型?

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

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

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

控制器类型之间有哪些基本区别?似乎没有关于何时使用哪个以及用于哪个用例的具体信息。 API 文档擅长告诉我它们每个的细节,但不告诉我何时使用它们。

View 和 Controller 之间的关系可能令人费解

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

事件是否与视图本身相关联(似乎是这样),如果是这样,您究竟在哪里与控制器单例交互以对其属性执行 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 在 Web 上进行应用程序开发的方向。这些概念看起来很简单,但冗长的是Objective-C(考虑到它的血统,这是有道理的),但我向上帝发誓,我觉得我正在与该死的框架作斗争,而不是我实际在我的应用程序上工作。语法的冗长和 API 文档之外的结构化文档的缺乏(让我们面对现实吧,300k 的 javascript 是大量的代码来抛出一些断点并尝试调试您的问题)。

我意识到你们面临的挑战,但希望这至少能让你们停下来思考一下如何让那些使用其他框架(或者地狱,甚至在其中工作过)的新开发人员的生活更轻松一个 MVC 框架,如 rails 或 django 或主干或 Angular)并说“这就是我们认为应该使用 ember 的方式”。

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

【问题讨论】:

    标签: ember.js


    【解决方案1】:

    请不要伤害任何孩子。 AFAIK ember-core 团队都超过 18 岁,因此任何与 ember-view 相关的挫败感显然更适合成年人。考虑到这一点...

    哪种控制器类型?

    你有正确的“什么”,但可能错过了“为什么”。控制器可能有点误导,尤其是来自导轨。将这些控制器单例视为代表应用程序的状态(内存中)。

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

    您可以只使用 Ember.Controller 来完成这一切,但 ObjectController 和 ArrayController 对于包装模型数据非常有用。任何重要的 ember 应用程序都可能会使用所有这三个。

    View 和 Controller 的关系

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

    • 从底层模型对象转换数据
    • 排序/过滤/选择对象列表
    • 反映应用程序状态

    connectOutlets 有什么问题? 您应该在此处使用请求的路由/上下文来决定应将哪些视图/数据插入应用程序的出口。控制器的 connectOutlet 方法有很多魔法让它变得简单,但也许魔法太多了。当你打电话时会发生什么(afaik): parentcontroller.connectOutlet 'child' 是

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

    在哪里做杂事?:通常在路由器上的操作中。起初这似乎很疯狂。想想 ember 路由器,它不像 rails,而是一个恰好也处理路由的 stateManager。在不久的将来,路由器 API 将更改以使这一点更加清晰。无论如何,使用路由器操作来执行诸如创建模型实例、提交/回滚事务和触发状态更改之类的事情。如果您使用 handlebars {{action}} 帮助器作为链接/按钮,这很容易做到,因为它默认以路由器为目标。

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

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

    模型 WTF?

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

    相反,您应该使用 ember-data。在过去的几个月里,它确实得到了发展,应该成为任何新的、非平凡的 ember 应用程序的默认选择。 @tomdale 刚刚就这个话题做了一个很棒的演讲,我建议你看看:https://speakerdeck.com/tomdale/ember-data-internals

    用 ember 构建模块化 UI 组件的“正确”方法是什么?

    用于构建模块化 UI 组件:

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

    用于构建单个应用程序:

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

    构建模块化 UI 组件与构建应用程序是完全不同的问题。 Ember.View 及其子类就是为此目的而设计的。您可以轻松扩展/组合它们以组合具有自定义行为的小部件,并在应用程序之间共享这些小部件。

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

    ember-bootstrap 项目就是一个很好的真实示例。通过阅读该项目的源代码,我学到了很多关于使用 ember-views 的知识。 http://emberjs-addons.github.com/ember-bootstrap/

    TLDR

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-10
      • 2018-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-14
      相关资源
      最近更新 更多