DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> JavaScript綜合知識 >> 簡述AngularJS相關的一些編程思想
簡述AngularJS相關的一些編程思想
編輯:JavaScript綜合知識     

 

  這篇文章主要介紹了AngularJS相關的一些編程思想,AngularJS是一款熱門的JavaScript庫,推薦!需要的朋友可以參考下

  在過去的幾個月裡,我一直遨游於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,你也會熟悉這種模式。

? 1 2 3 4 5 6 7 8 9 10 11 // 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)。但是如你所見,即使是文檔和建議步驟任然過時地建議你使用全局作用域:

        這樣做,極棒的事情將出現。

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

       -- Angular.js文檔

         使用模塊(modules)允許我們以下面的方式重寫控制器(controllers):

? 1 2 3 4 5 6 7 8 9 10 11 12 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來做元素之上的類操作。

? 1 2 3 4 5 6 7 8 9 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,替代之。

? 1 2 3 4 5 6 7 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 強制你寫好的代碼,但是更深一層說,它強制你去思考。一會兒後,它就像一個服務器端的實現,或者成為一個不堪忍受的“黑客大會”。這些都取決於你這麼選擇。

  接近完美

 

  讓我們來解析一下我們應用程序的各部件的其中之一,層。

? 1 2 3 4 5 6 7 8 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代碼的文章。特別是,我樂於探討一些在升級我的代碼的時候,所遇到的一些邊緣的案例,如何解決其中的問題,同時讓其余的部分同樣工作。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved