搜索
首页web前端js教程简述AngularJS相关的一些编程思想_AngularJS

 在过去的几个月里,我一直遨游于Angular的世界。如今回想起来,很难想象在没有类似于Angular.js, Backbone.js以及其伙伴Underscore.js这些数据绑定框架下我每天如何去编写一个大型前端应用。我不敢相信我已经用它们完成了那件工作。

可能我有点小偏见,但考虑到我一直在做的应用是在浏览器中实现Photoshop类型的编辑器,它呈现相同的数据有几种完全不一样的方式。

  •     图层以图形化的形式呈现,占据了屏幕的大部份。它们列于一个面板内,你可以删除它们。
  •     当你选中一个图层时,它的边缘会被虚线包围,同时会高亮显示于列表中。
  •     类似地,图层在面板中的尺寸和它们的大小这些属性取决于画布。
  •     我上面提到过的面板是可以拖拽,折叠,关闭的。


如果不是一个像Augular的框架,这一种类的互动、数据连接和视图同步很容易变成一个持续的噩梦。有能力修正一个地方的模型和用Augular修正所有相关的视图听起来几乎像在骗人。添加、消除或者改动一个层次只是一个改变对象的问题。层次,x+=10,完成。并没有地方需要手动作废视图、手工地修改在DOM的层次中的每一个实例,甚至是因为这个问题而去与DOM互动。

Augular使我们可以去到我们从未想过的地方,像设置一串使我们能够在现有的环境下做出申请的键盘捷径。举个例子,文件编辑捷径(像?B:用于切换黑体文本)只是使我们能够编辑一个文件层面。

201562395829701.png (151×117)

 同样地,我们为这些快捷键附加了一个描述(通过一个我们创建的服务进行注册),然后我们可以显示一个快捷键的列表,同时还有它们的描述,在一个便利条上。此外,我们写了一个指令使得我们可以将单独的DOM元素与它们的快捷键绑定在一起,当你的鼠标在元素上停留一会,会出现一个提示,让你知道此时可用的快捷键。

  •     Angular可以使我们做到我们做梦也想不到的事情。

老实说,这就好像我们已经不是在编写一个web应用。web只是媒介。当我们增进了我们对Angular的理解后,代码变得更加模块化,更加独立,并且更加连接交互。它很自然地变得更加Angular了。


然后通过Augular,我的意思是在Augular背后的那些高度互动的丰富的应用开发哲学。javascript,一个让我们能够开发那些一段时间前我们还觉得不可能的一部分软件的相似的东西。

201562395953032.png (816×304)

 我们甚至有能力去开发一个成熟的用于修改DOM变成历史中现在选中的点的历史控制板,并让它工作得很好。至少可以这么说,当你兴奋的返回历史控制板查看那些与Augular能力相关的数据在你的视图工作中完美的更新每一个微小的细节。

那并不总是容易的,基本代码总是变成一场无可控制的混乱。
 

的确,在过去几周里我们一直在更新并且将我们的前端整个架构重写。在我们开始重新编写以前,看一下自从0.10.6以来,将Angular更新得有优势的过程。如果看了变更日志,你就知道这是一个相当长的过程。

在这个重构的过程里,我们从以错误的方法对待Angular,转变为以Angular的方式对待Angular。

在我们的案例中,错误的方法包含了许多的问题,我们不得不在此时,在使我们的代码基础到达可爱状态之前,解决它们。

在全局作用域声明控制器(Controllers)

这是一个 Angular 初学者容易做的例子。如果你熟悉 Angular,你也会熟悉这种模式。
 

// winds up on window.LoginCtrl ...
var LoginCtrl = function ($scope, dep1, dep2) {
  // scope defaults
};
 
LoginCtrl.prototype.resetPassword = function () {
  // reset password button click handler 
};
 
// more on this one later
LoginCtrl.$inject = ['$scope', dep1', 'dep2'];

这段代码没有包含在闭包中,或者说,所有的声明都在根作用域,全局的 window 对象上,混蛋啊。用正宗的 Angular 方式来写的话是使用它提供的模块 api ( module API)。但是如你所见,即使是文档和建议步骤任然过时地建议你使用全局作用域:

    这样做,极棒的事情将出现。
 

  // A Controller for your app
  var XmplController = function($scope, greeter, user) {
   $scope.greeting = greeter.greet(user.name);
  }

    -- Angular.js文档

使用模块(modules)允许我们以下面的方式重写控制器(controllers):
 

angular.module('myApp').controller('loginCtrl', [
  '$scope', 'dep1', 'dep2',
  function ($scope, dep1, dep2) {
    'use strict';
 
    // scope defaults
 
    $scope.resetPassword = function () {
      // reset password button click handler
    };
  }
]);

我发现使用 Angular 控制器的漂亮做法是你必须在所有地方使用控制器方法(controller function),因为你需要控器的依赖注入,而且控制器提供了新的作用域,绑定我们从需求到封装我们所有的脚本文件成为自调用函数表达式( self-invoking function expressions),像这样 (function(){})()。

依赖$injection
在最早的例子中你可能已经注意到了, 依赖是使用$inject注入的. 另一方面,大部份的模块API, 允许你传入一个函数作为参数, 或者一个包含了依赖的数组作为参数, 其后面跟着一个依赖于这些依赖的函数. 这是在Angular中我不喜欢的一点 , 但这应该是它文档的过错. 在文档中的大部份例子认为你并不需要一个数组形式的参数; 但现实是,你是需要的。 如果你在使用一个压缩器压缩你的代码之前, 没有运行ngmin , 事情将会变得糟糕.


由于你没有使用数组格式['$scope',...]明确声明你的依赖包,你看上去简洁的方法参数将会被缩略成类似于b,c,d,e的样子,有效地扼杀了Angular的依赖注入能力。我认为他们构建框架的思路存在了重大的失误,这与我在非常不喜欢 Require.js 和他们麻烦的 AMD 模块最后的推论是相似的。

    如果他不能在产品中使用,它还有什么用?

我的这种态度是因为你在产品中所使用的框架里,有一部分代码是已经写死了的。这对于开发中经常用到、产品中偶尔用到的实用工具,诸如控制台和错误报告,是很好的。如果语法上的甜头(可读性)只用在开发中,就会变得没有任何意义。

这些破事让我很愤怒, 现在发泄完了. 谈谈$符吧...

减少 jQuery扩散

深入的讲, 这个应用是 "类Angular程序", 也就是说它只是包裹于Angular之中, 大多数DOM 交互是经由jQuery处理的, 这给Angular带来相当多的争论。

    如果今天我要从头开始写一款Angular.js应用,我不会立即包含进jQuery。我会强迫自己使用  angular.element 来代替。

如果jQuery存在的话,angular.element这个API将包装它,同时它给Angular团队实现 jQuery的API提供了可以替代的选择,名为jqLite。这并不是说 jQuery不好,或者说我们需要另一个某种实现,来映射它们的API。只是因为使用jQuery显得不是那么有Angular的思想。


让我们来看一个具体的,愚蠢的,例子。在controller被声明的地方,它使用jQuery来做元素之上的类操作。
 

div.foo(ng-controller='fooCtrl')
 
angular.module('foo').controller('fooCtrl', function ($scope) {
  $('.foo').addClass('foo-init');
 
  $scope.$watch('something', function () {
    $('.foo').toggleClass('foo-something-else');
  });
});

然而,我们可以用我们期望的方法来使用Angular,替代之。
 

angular.module('foo').controller('fooCtrl', function ($scope, $element) {
  $element.addClass('foo-init');
 
  $scope.$watch('something', function () {
    $element.toggleClass('foo-something-else');
  });
});

最后一行你不能直接,或者通过jQuery来操作DOM(改变属性,增添事件监听器)。你应该使用指令来替代。那篇文章很棒,去读读看。

如果你仍然jQuery化了,有许多文章可以一读,例如这篇迁移指南,还有我的关于怎样使用jQuery的批判性思考 这篇文章。


我不是要声明我们准备完全移除 jQuery 。我们有其他更重要的目标,例如,发布我们的产品。这个时候,删除 jQuery 的依赖还是很有意义的。这样做能够使我们的控制器得到简化,我们创建处理 DOM 的指令,使用 angular.element 即使它实际上映射着 jQuery 。

我们依赖着有点恶心的 jQuery UI,我们当然不只是为了它的对话框而使用它,它还有很多用途。例如,拖动一个列表项然后把它放到一个已排序的列表中,如果不使用 jQuery UI,这将牵涉到一大堆代码。因此,实际上,对于 jQuery UI 来说,并没有真正很好的替代品。拖拽的功能可以通过一个轻量级的拖拽库 angular-dragon-drop 来替代,但是,对于元素排序插件,还是得依赖 jQuery UI 。

管理代码库

还有一个我们在迁移中需要解决的问题是整个代码库都挤在一个单一的大文件中。这个文件包含了所有控制器、所有服务、所有指令以及每个控制器的特定代码。我指出一点使得我们可以准确地把每个文件只包含一个组件。目前,我们有很少的文件,却包含了不知一个组件。大多数是因为一个指令使用一个服务来与外界共享数据。

尽管和 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代码的文章。特别是,我乐于探讨一些在升级我的代码的时候,所遇到的一些边缘的案例,如何解决其中的问题,同时让其余的部分同样工作。

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
Python vs. JavaScript:开发人员的比较分析Python vs. JavaScript:开发人员的比较分析May 09, 2025 am 12:22 AM

Python和JavaScript的主要区别在于类型系统和应用场景。1.Python使用动态类型,适合科学计算和数据分析。2.JavaScript采用弱类型,广泛用于前端和全栈开发。两者在异步编程和性能优化上各有优势,选择时应根据项目需求决定。

Python vs. JavaScript:选择合适的工具Python vs. JavaScript:选择合适的工具May 08, 2025 am 12:10 AM

选择Python还是JavaScript取决于项目类型:1)数据科学和自动化任务选择Python;2)前端和全栈开发选择JavaScript。Python因其在数据处理和自动化方面的强大库而备受青睐,而JavaScript则因其在网页交互和全栈开发中的优势而不可或缺。

Python和JavaScript:了解每个的优势Python和JavaScript:了解每个的优势May 06, 2025 am 12:15 AM

Python和JavaScript各有优势,选择取决于项目需求和个人偏好。1.Python易学,语法简洁,适用于数据科学和后端开发,但执行速度较慢。2.JavaScript在前端开发中无处不在,异步编程能力强,Node.js使其适用于全栈开发,但语法可能复杂且易出错。

JavaScript的核心:它是在C还是C上构建的?JavaScript的核心:它是在C还是C上构建的?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc; saninterpretedlanguagethatrunsonenginesoftenwritteninc.1)javascriptwasdesignedAsalightweight,解释edganguageforwebbrowsers.2)Enginesevolvedfromsimpleterterterpretpreterterterpretertestojitcompilerers,典型地提示。

JavaScript应用程序:从前端到后端JavaScript应用程序:从前端到后端May 04, 2025 am 12:12 AM

JavaScript可用于前端和后端开发。前端通过DOM操作增强用户体验,后端通过Node.js处理服务器任务。1.前端示例:改变网页文本内容。2.后端示例:创建Node.js服务器。

Python vs. JavaScript:您应该学到哪种语言?Python vs. JavaScript:您应该学到哪种语言?May 03, 2025 am 12:10 AM

选择Python还是JavaScript应基于职业发展、学习曲线和生态系统:1)职业发展:Python适合数据科学和后端开发,JavaScript适合前端和全栈开发。2)学习曲线:Python语法简洁,适合初学者;JavaScript语法灵活。3)生态系统:Python有丰富的科学计算库,JavaScript有强大的前端框架。

JavaScript框架:为现代网络开发提供动力JavaScript框架:为现代网络开发提供动力May 02, 2025 am 12:04 AM

JavaScript框架的强大之处在于简化开发、提升用户体验和应用性能。选择框架时应考虑:1.项目规模和复杂度,2.团队经验,3.生态系统和社区支持。

JavaScript,C和浏览器之间的关系JavaScript,C和浏览器之间的关系May 01, 2025 am 12:06 AM

引言我知道你可能会觉得奇怪,JavaScript、C 和浏览器之间到底有什么关系?它们之间看似毫无关联,但实际上,它们在现代网络开发中扮演着非常重要的角色。今天我们就来深入探讨一下这三者之间的紧密联系。通过这篇文章,你将了解到JavaScript如何在浏览器中运行,C 在浏览器引擎中的作用,以及它们如何共同推动网页的渲染和交互。JavaScript与浏览器的关系我们都知道,JavaScript是前端开发的核心语言,它直接在浏览器中运行,让网页变得生动有趣。你是否曾经想过,为什么JavaScr

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具