欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

簡(jiǎn)述AngularJS相關(guān)的一些編程思想

 更新時(shí)間:2015年06月23日 10:08:06   投稿:goldensun  
這篇文章主要介紹了AngularJS相關(guān)的一些編程思想,AngularJS是一款熱門的JavaScript庫,推薦!需要的朋友可以參考下

 在過去的幾個(gè)月里,我一直遨游于Angular的世界。如今回想起來,很難想象在沒有類似于Angular.js, Backbone.js以及其伙伴Underscore.js這些數(shù)據(jù)綁定框架下我每天如何去編寫一個(gè)大型前端應(yīng)用。我不敢相信我已經(jīng)用它們完成了那件工作。

可能我有點(diǎn)小偏見,但考慮到我一直在做的應(yīng)用是在瀏覽器中實(shí)現(xiàn)Photoshop類型的編輯器,它呈現(xiàn)相同的數(shù)據(jù)有幾種完全不一樣的方式。

  •     圖層以圖形化的形式呈現(xiàn),占據(jù)了屏幕的大部份。它們列于一個(gè)面板內(nèi),你可以刪除它們。
  •     當(dāng)你選中一個(gè)圖層時(shí),它的邊緣會(huì)被虛線包圍,同時(shí)會(huì)高亮顯示于列表中。
  •     類似地,圖層在面板中的尺寸和它們的大小這些屬性取決于畫布。
  •     我上面提到過的面板是可以拖拽,折疊,關(guān)閉的。


如果不是一個(gè)像Augular的框架,這一種類的互動(dòng)、數(shù)據(jù)連接和視圖同步很容易變成一個(gè)持續(xù)的噩夢(mèng)。有能力修正一個(gè)地方的模型和用Augular修正所有相關(guān)的視圖聽起來幾乎像在騙人。添加、消除或者改動(dòng)一個(gè)層次只是一個(gè)改變對(duì)象的問題。層次,x+=10,完成。并沒有地方需要手動(dòng)作廢視圖、手工地修改在DOM的層次中的每一個(gè)實(shí)例,甚至是因?yàn)檫@個(gè)問題而去與DOM互動(dòng)。

Augular使我們可以去到我們從未想過的地方,像設(shè)置一串使我們能夠在現(xiàn)有的環(huán)境下做出申請(qǐng)的鍵盤捷徑。舉個(gè)例子,文件編輯捷徑(像?B:用于切換黑體文本)只是使我們能夠編輯一個(gè)文件層面。

201562395829701.png (151×117)

 同樣地,我們?yōu)檫@些快捷鍵附加了一個(gè)描述(通過一個(gè)我們創(chuàng)建的服務(wù)進(jìn)行注冊(cè)),然后我們可以顯示一個(gè)快捷鍵的列表,同時(shí)還有它們的描述,在一個(gè)便利條上。此外,我們寫了一個(gè)指令使得我們可以將單獨(dú)的DOM元素與它們的快捷鍵綁定在一起,當(dāng)你的鼠標(biāo)在元素上停留一會(huì),會(huì)出現(xiàn)一個(gè)提示,讓你知道此時(shí)可用的快捷鍵。

  •     Angular可以使我們做到我們做夢(mèng)也想不到的事情。

老實(shí)說,這就好像我們已經(jīng)不是在編寫一個(gè)web應(yīng)用。web只是媒介。當(dāng)我們?cè)鲞M(jìn)了我們對(duì)Angular的理解后,代碼變得更加模塊化,更加獨(dú)立,并且更加連接交互。它很自然地變得更加Angular了。


然后通過Augular,我的意思是在Augular背后的那些高度互動(dòng)的豐富的應(yīng)用開發(fā)哲學(xué)。javascript,一個(gè)讓我們能夠開發(fā)那些一段時(shí)間前我們還覺得不可能的一部分軟件的相似的東西。

201562395953032.png (816×304)

 我們甚至有能力去開發(fā)一個(gè)成熟的用于修改DOM變成歷史中現(xiàn)在選中的點(diǎn)的歷史控制板,并讓它工作得很好。至少可以這么說,當(dāng)你興奮的返回歷史控制板查看那些與Augular能力相關(guān)的數(shù)據(jù)在你的視圖工作中完美的更新每一個(gè)微小的細(xì)節(jié)。

那并不總是容易的,基本代碼總是變成一場(chǎng)無可控制的混亂。
 

的確,在過去幾周里我們一直在更新并且將我們的前端整個(gè)架構(gòu)重寫。在我們開始重新編寫以前,看一下自從0.10.6以來,將Angular更新得有優(yōu)勢(shì)的過程。如果看了變更日志,你就知道這是一個(gè)相當(dāng)長(zhǎng)的過程。

在這個(gè)重構(gòu)的過程里,我們從以錯(cuò)誤的方法對(duì)待Angular,轉(zhuǎn)變?yōu)橐訟ngular的方式對(duì)待Angular。

在我們的案例中,錯(cuò)誤的方法包含了許多的問題,我們不得不在此時(shí),在使我們的代碼基礎(chǔ)到達(dá)可愛狀態(tài)之前,解決它們。

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

這是一個(gè) Angular 初學(xué)者容易做的例子。如果你熟悉 Angular,你也會(huì)熟悉這種模式。
 

// 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 對(duì)象上,混蛋啊。用正宗的 Angular 方式來寫的話是使用它提供的模塊 api ( module API)。但是如你所見,即使是文檔和建議步驟任然過時(shí)地建議你使用全局作用域:

    這樣做,極棒的事情將出現(xiàn)。
 

  // 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
    };
  }
]);

我發(fā)現(xiàn)使用 Angular 控制器的漂亮做法是你必須在所有地方使用控制器方法(controller function),因?yàn)槟阈枰仄鞯囊蕾囎⑷?,而且控制器提供了新的作用域,綁定我們從需求到封裝我們所有的腳本文件成為自調(diào)用函數(shù)表達(dá)式( self-invoking function expressions),像這樣 (function(){})()。

依賴$injection
在最早的例子中你可能已經(jīng)注意到了, 依賴是使用$inject注入的. 另一方面,大部份的模塊API, 允許你傳入一個(gè)函數(shù)作為參數(shù), 或者一個(gè)包含了依賴的數(shù)組作為參數(shù), 其后面跟著一個(gè)依賴于這些依賴的函數(shù). 這是在Angular中我不喜歡的一點(diǎn) , 但這應(yīng)該是它文檔的過錯(cuò). 在文檔中的大部份例子認(rèn)為你并不需要一個(gè)數(shù)組形式的參數(shù); 但現(xiàn)實(shí)是,你是需要的。 如果你在使用一個(gè)壓縮器壓縮你的代碼之前, 沒有運(yùn)行ngmin , 事情將會(huì)變得糟糕.


由于你沒有使用數(shù)組格式['$scope',...]明確聲明你的依賴包,你看上去簡(jiǎn)潔的方法參數(shù)將會(huì)被縮略成類似于b,c,d,e的樣子,有效地扼殺了Angular的依賴注入能力。我認(rèn)為他們構(gòu)建框架的思路存在了重大的失誤,這與我在非常不喜歡 Require.js 和他們麻煩的 AMD 模塊最后的推論是相似的。

    如果他不能在產(chǎn)品中使用,它還有什么用?

我的這種態(tài)度是因?yàn)槟阍诋a(chǎn)品中所使用的框架里,有一部分代碼是已經(jīng)寫死了的。這對(duì)于開發(fā)中經(jīng)常用到、產(chǎn)品中偶爾用到的實(shí)用工具,諸如控制臺(tái)和錯(cuò)誤報(bào)告,是很好的。如果語法上的甜頭(可讀性)只用在開發(fā)中,就會(huì)變得沒有任何意義。

這些破事讓我很憤怒, 現(xiàn)在發(fā)泄完了. 談?wù)?符吧...

減少 jQuery擴(kuò)散

深入的講, 這個(gè)應(yīng)用是 "類Angular程序", 也就是說它只是包裹于Angular之中, 大多數(shù)DOM 交互是經(jīng)由jQuery處理的, 這給Angular帶來相當(dāng)多的爭(zhēng)論。

    如果今天我要從頭開始寫一款A(yù)ngular.js應(yīng)用,我不會(huì)立即包含進(jìn)jQuery。我會(huì)強(qiáng)迫自己使用  angular.element 來代替。

如果jQuery存在的話,angular.element這個(gè)API將包裝它,同時(shí)它給Angular團(tuán)隊(duì)實(shí)現(xiàn) jQuery的API提供了可以替代的選擇,名為jqLite。這并不是說 jQuery不好,或者說我們需要另一個(gè)某種實(shí)現(xiàn),來映射它們的API。只是因?yàn)槭褂胘Query顯得不是那么有Angular的思想。


讓我們來看一個(gè)具體的,愚蠢的,例子。在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(改變屬性,增添事件監(jiān)聽器)。你應(yīng)該使用指令來替代。那篇文章很棒,去讀讀看。

如果你仍然jQuery化了,有許多文章可以一讀,例如這篇遷移指南,還有我的關(guān)于怎樣使用jQuery的批判性思考 這篇文章。


我不是要聲明我們準(zhǔn)備完全移除 jQuery 。我們有其他更重要的目標(biāo),例如,發(fā)布我們的產(chǎn)品。這個(gè)時(shí)候,刪除 jQuery 的依賴還是很有意義的。這樣做能夠使我們的控制器得到簡(jiǎn)化,我們創(chuàng)建處理 DOM 的指令,使用 angular.element 即使它實(shí)際上映射著 jQuery 。

我們依賴著有點(diǎn)惡心的 jQuery UI,我們當(dāng)然不只是為了它的對(duì)話框而使用它,它還有很多用途。例如,拖動(dòng)一個(gè)列表項(xiàng)然后把它放到一個(gè)已排序的列表中,如果不使用 jQuery UI,這將牽涉到一大堆代碼。因此,實(shí)際上,對(duì)于 jQuery UI 來說,并沒有真正很好的替代品。拖拽的功能可以通過一個(gè)輕量級(jí)的拖拽庫 angular-dragon-drop 來替代,但是,對(duì)于元素排序插件,還是得依賴 jQuery UI 。

管理代碼庫

還有一個(gè)我們?cè)谶w移中需要解決的問題是整個(gè)代碼庫都擠在一個(gè)單一的大文件中。這個(gè)文件包含了所有控制器、所有服務(wù)、所有指令以及每個(gè)控制器的特定代碼。我指出一點(diǎn)使得我們可以準(zhǔn)確地把每個(gè)文件只包含一個(gè)組件。目前,我們有很少的文件,卻包含了不知一個(gè)組件。大多數(shù)是因?yàn)橐粋€(gè)指令使用一個(gè)服務(wù)來與外界共享數(shù)據(jù)。

盡管和 Angular 無關(guān),我們還是把我們的 CSS 樣式表(stylesheet)模塊化。我們?yōu)槊總€(gè)組件中使用的 CSS 類名前面都加上了兩個(gè)字的前綴。例如, .pn- 作為前綴,代表面板(panel); .ly- 前綴,代表著圖層(layer)等等。這樣做的直接好處就是,你不需要再費(fèi)勁地想哪個(gè)組件的 CSS 類是怎樣的了。因?yàn)槟阋呀?jīng)為它們?cè)O(shè)置了命名空間,你就很少會(huì)重復(fù)用到某一個(gè) CSS 類名了。另一個(gè)好處就是減少了嵌套,我們以前曾經(jīng)用 #layoutEditor div.layer .handle div 這樣復(fù)雜的選擇器表達(dá)式,而現(xiàn)在,我們只需要 .ly-handle-content 就可以了。深度的嵌套現(xiàn)在只發(fā)生在額外的選擇器覆蓋上,例如 .foobar[disabled]:hover,或者,最壞的情況下,像 .foo-bar .br-baz 。


下面是一些我們定下的 CSS 類命名規(guī)則:

  •     用兩個(gè)字符來描述組件名:.ly-、.dd-、.dg-等等
  •     采用 .ly-foo-barname 來代替嵌套命名 .ly-foo .bar
  •     避免內(nèi)聯(lián)樣式,總是使用 CSS 類名。這能夠減少不界面的一致性,提高語義解釋能力
  •     不要在 CSS 中使用 ID 來賦值

在實(shí)現(xiàn)了這套面向組件的 CSS 聲明方法后,我又想了很久“the class soup way”。

Angular 強(qiáng)制你寫好的代碼,但是更深一層說,它強(qiáng)制你去思考。一會(huì)兒后,它就像一個(gè)服務(wù)器端的實(shí)現(xiàn),或者成為一個(gè)不堪忍受的“黑客大會(huì)”。這些都取決于你這么選擇。

接近完美

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

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類,也就是說這個(gè)元素是canvas組件的一部分(canvas指的使我們繪制層的地方,不要和HTML5canvas混淆)。然后,我們 在foreach類似的循環(huán)里面 使用ngRepeat標(biāo)簽來為每一個(gè)層的建立一個(gè)相似的元素。并且通過一個(gè)我們所寫的反向的filter來傳遞,所以,最后一個(gè)層位于最上部,而且對(duì)用戶可見。apLayer標(biāo)簽,其實(shí)是為了繪制層的任務(wù)所采用的,不論是一個(gè)圖片,或者是某些文字,HTML,或別的東西。event標(biāo)簽(ng-mousedown, ng-mouseup, ng-dblclick) 僅僅是簡(jiǎn)單的為事件做代理而用,這些事件將被我們的層選擇服務(wù)來處理。最后,ngHide這個(gè)標(biāo)簽,我想就不必多言了吧。


這么一大堆功能(譯者注:有點(diǎn)夸張了),而Angular成功的使它看上去如此簡(jiǎn)單,用可讀的HTML,從某種程度上就告訴了你它們是怎么回事。更多的是,它使得你可以分解開不同的需要考慮的問題,從而你能夠?qū)懗鰜砗?jiǎn)潔的代碼,不需要一次把所有的事情都考慮在內(nèi)。簡(jiǎn)而言之,它降低了復(fù)雜度(譯者注:其實(shí)Angular本身就很復(fù)雜,呵呵),讓復(fù)雜變的簡(jiǎn)單。而讓“難以簡(jiǎn)單度量的問題”,變的可能。

我期待不久會(huì)有更多關(guān)于Angular代碼的文章。特別是,我樂于探討一些在升級(jí)我的代碼的時(shí)候,所遇到的一些邊緣的案例,如何解決其中的問題,同時(shí)讓其余的部分同樣工作。

相關(guān)文章

最新評(píng)論