还有一个我们在迁移中需要解决的问题是整个代码库都挤在一个单一的大文件中。这个文件包含了所有控制器、所有服务、所有指令以及每个控制器的特定代码。我指出一点使得我们可以准确地把每个文件只包含一个组件。目前,我们有很少的文件,却包含了不知一个组件。大多数是因为一个指令使用一个服务来与外界共享数据。
尽管和 Angular 无关,我们还是把我们的 CSS 样式表(stylesheet)模块化。我们为每个组件中使用的 CSS 类名前面都加上了两个字的前缀。例如, .pn- 作为前缀,代表面板(panel); .ly- 前缀,代表着图层(layer)等等。这样做的直接好处就是,你不需要再费劲地想哪个组件的 CSS 类是怎样的了。因为你已经为它们设置了命名空间,你就很少会重复用到某一个 CSS 类名了。另一个好处就是减少了嵌套,我们以前曾经用 #layoutEditor div.layer .handle div 这样复杂的选择器表达式,而现在,我们只需要 .ly-handle-content 就可以了。深度的嵌套现在只发生在额外的选择器覆盖上,例如 .foobar[disabled]:hover,或者,最坏的情况下,像 .foo-bar .br-baz 。
下面是一些我们定下的 CSS 类命名规则:
用两个字符来描述组件名:.ly-、.dd-、.dg-等等
采用 .ly-foo-barname 来代替嵌套命名 .ly-foo .bar
避免内联样式,总是使用 CSS 类名。这能够减少不界面的一致性,提高语义解释能力
不要在 CSS 中使用 ID 来赋值
在实现了这套面向组件的 CSS 声明方法后,我又想了很久“the class soup way”。
Angular 强制你写好的代码,但是更深一层说,它强制你去思考。一会儿后,它就像一个服务器端的实现,或者成为一个不堪忍受的“黑客大会”。这些都取决于你这么选择。
接近完美
让我们来解析一下我们应用程序的各部件的其中之一,层。
div.cv-layer( ng-repeat="layer in page.layers | reverse", ap-layer, ng-mousedown="selectLayer(layer.id)", ng-mouseup="selectLayer(layer.id)", ng-dblclick="doubleClickLayer(layer)", ng-hide="layer.invisible" )
这里,我们使用了cv-layer类,也就是说这个元素是canvas组件的一部分(canvas指的使我们绘制层的地方,不要和HTML5canvas混淆)。然后,我们 在foreach类似的循环里面 使用ngRepeat标签来为每一个层的建立一个相似的元素。并且通过一个我们所写的反向的filter来传递,所以,最后一个层位于最上部,而且对用户可见。apLayer标签,其实是为了绘制层的任务所采用的,不论是一个图片,或者是某些文字,HTML,或别的东西。event标签(ng-mousedown, ng-mouseup, ng-dblclick) 仅仅是简单的为事件做代理而用,这些事件将被我们的层选择服务来处理。最后,ngHide这个标签,我想就不必多言了吧。
这么一大堆功能(译者注:有点夸张了),而Angular成功的使它看上去如此简单,用可读的HTML,从某种程度上就告诉了你它们是怎么回事。更多的是,它使得你可以分解开不同的需要考虑的问题,从而你能够写出来简洁的代码,不需要一次把所有的事情都考虑在内。简而言之,它降低了复杂度(译者注:其实Angular本身就很复杂,呵呵),让复杂变的简单。而让“难以简单度量的问题”,变的可能。
我期待不久会有更多关于Angular代码的文章。特别是,我乐于探讨一些在升级我的代码的时候,所遇到的一些边缘的案例,如何解决其中的问题,同时让其余的部分同样工作。
您可能感兴趣的文章: