16

我正在尝试了解构建 ember.js 应用程序的最佳实践。这张来自tomdale的幻灯片:

https://speakerdeck.com/u/tomdale/p/emberjs-more-than-meets-the-eye?slide=55

简明扼要地描述了如何分配应用程序逻辑。但是,在尝试遵循这些准则时,我发现了一些问题:

  1. 路由器变得太大。根据介绍,路由器“响应来自视图的事件”,但是当有几十个视图时,这会导致大量代码。
  2. 有大量的控制器。在 Rails 应用程序中,CRUD 操作通常驻留在同一个控制器中,但是对于 ember 应用程序,似乎应该有一个控制器来列出记录、一个控制器来查看记录、一个控制器来创建记录等。

感觉不是很干,因为我最终在控制器、视图和车把模板之间有这么多文件,每个模板只有几行代码。

我正在尝试确定问题是否在于我错误地应用了指南,或者这些指南是否仅适用于琐碎的应用程序。

有没有人有任何建议 - 特别是关于如何管理路由器的增长?

4

2 回答 2

19

我认为说 Ember 鼓励太多控制器就像说 Javascript 鼓励太多功能一样。是的,你可以疯狂地扩散任何一个。或者你可以做相反的事情,让它完全按照你的需要工作。一般来说,请始终记住,您的应用程序应该完全按照它需要的那样复杂,而且不能再复杂了。你不需要仅仅因为某个著名的程序员使用了某种架构或模式,甚至因为它似乎是“Ember 方式”。甚至像关注点分离、MVC 等“通用的好东西”也是您应该尝试完全理解的原则和模型,然后在它们满足您需求的范围内使用它们。我认为,出于正确的原因有选择地打破规则和模式的能力比对编程之神教条的盲目奉献更能说明一个伟大的黑客的标志。这是一门手艺,不是宗教。(但是 YMMV。也许有一个特殊的地狱圈是为像我这样的程序员保留的。我打赌它。)

具体到 Ember,我倾向于围绕我的数据模型和/或围绕特定用户工作流使用控制器,而不是围绕每个视图。然后使用路由/状态管理器作为视图之间的粘合剂,我通常在视图上使用事件管理器来处理每个视图内的浏览器事件,包括向路由器发送指令。因此,如果我有一个围绕客户和产品的应用程序,我将为每个应用程序设置一个控制器,就像我在 Rails 中所做的那样。这将导致每个控制器拥有比某些人喜欢在一个地方拥有的更多功能和计算属性。这也意味着我不一定能在另一个上下文中重用我的视图,因为它们是硬连接到控制器的。是的,这是糟糕的关注点分离。但是,如果它导致没有回报的复杂性,那也不是绝对的好。

同样关于控制器的主题,我认为人们特别倾向于为您的主要数据模型的子集不必要地增加控制器。假设您有一个产品控制器,并且您希望将给定用户正在收集的产品存储在比较工具中。大多数人似乎为此创建了一个新控制器,但是将它们推送到 Products 控制器或 Customers 控制器或 Customer 模型中的附加数组或其他 Enumerable 是完全合法的。这使依赖于相同功能和属性的对象保持在更近的范围内。这content每个控制器中的对象是,AFAIK,只是另一个 Enumerable。它有一些对控制器的特殊隐式引用,但并不神奇。我没有发现不使用其他功能的原因。它们与绑定、with#each等也一样有效。

类似地,有些人只是喜欢将他们的应用程序分解成一百万个文件,将它们嵌套在文件结构中的 15 层等。如果这有助于您可视化底层逻辑,并让其他人清楚地了解,那么您将获得更多的权力你的团队。对我来说,它只会让我在只有 1-3 人的工程团队的项目上放慢速度。人们还倾向于复制他们熟悉的其他 MVC 系统(如 Rails)的基于文件的样式,其中文件是分离视图和其他逻辑对象的必要显式结构。这成为信条和根深蒂固的习惯。但是在 Javascript MVC 中,我发现它通常没有这样的目的,并且对于隐式设计来说是严格冗余的。我倾向于为我的整个 Ember 应用程序使用一个精心组织的文件(将其与任何其他非库 JS 分开),有很多缩进和嵌套,这有助于我可视化层次结构。无论您做什么,就文件而言,它在运行时都是一样的,只要您在正确的时间将它们全部交付到正确的位置。使用 Ember 和 JS,文件结构只满足您团队的需求,仅此而已。相应地校准。

(重要警告:如果您确实使用了一百万个文件,则最好使用预编译器将它们一起显示以交付给用户,否则您将在单独交付所有这些文件时承受巨大的延迟.)

(另一个重要的警告:对于一个大型团队或像 GitHub 这样的快速每日发布计划,基于文件的逻辑分离可以使版本控制比在同一个文件中进行大量合并更容易,因为合并工具可能会混淆。再次,这是管理和监控您的人工流程以及仔细进行合并的问题,而不是您的 JS 框架强加的技术要求。)

(最后重要的警告:再一次,有时技术要求和人/程序要求之间的区别是模糊的。如果你破坏了开发人员的大脑,你也往往会拥有一个坏掉的应用程序。所以,做对人和流程有用的事情你必须处理它的构建。)

正如我之前所说,YMMV。我不是程序员之神,从我的声誉分数可以看出,所以你可以随意无视我。但我支持这样的想法,即您应该只使用尽可能多的复杂性、尽可能多的文件结构和尽可能多的高级抽象(如路由,这实际上对于用途有限的单页应用程序来说可能是多余的)。您的需求; 仅此而已。

于 2012-08-10T16:58:47.160 回答
8

我认为我们正在开发一个相当大的 ember 应用程序(目前大约有 45 个视图)。它意味着几乎相同数量的控制器和模板)。事实上,我们的路由器非常大,但我们可以通过将其拆分为多个文件来轻松管理它。基本上,每个文件代表应用程序的一个屏幕,并负责维护一个功能集。这是路由器的摘录:

Router = Ember.Router.extend({
  root: Ember.Route.extend({

  index: Ember.Route.extend({
    route: '/',

  unlogged: Ember.Route.extend({
    route: 'welcome',

    connectOutlets: function (router) {
      var applicationController = router.get('applicationController');
      applicationController.connectOutlet('welcome');
    }
  }),

  logged: Ember.Route.extend({
    route: 'app',

    projects: Ember.Route.extend({
      route: 'projects',

      collection: ProjectsRoute,
      member: ProjectRoute,

      showProjects: function (router) {
        router.transitionTo('projects.collection');
      }
    })
  })
})

然后它在ProjectRoute. 每次在一条路线中似乎有很多功能时,我们都会将其拆分。您甚至可以重新打开一个路由来扩展它,并在其中插入其他功能。

ProjectState.reopen({

  scenarios: ScenariosRoute,

  showScenarios: function (router) {
    router.transitionTo('scenarios.collection');
  }
});

这意味着更多的文件,但如果组织良好,维护起来并不难,因为您很少同时处理所有功能。通常,我不会同时打开 4 个文件(视图、控制器、模板、路由)

我不知道这是否是最佳做法,但对我们来说效果很好

于 2012-07-24T19:24:28.637 回答