搜尋
首頁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)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

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

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能