當前位置:編程學習大全網 - 編程語言 - 如何用AngularJS編程思想

如何用AngularJS編程思想

AngularJS是壹款優秀的前端JS框架,已經被用於Google的多款產品當中。AngularJS有著諸多特性,最為核心的是:MVC、模塊化、自動化雙向數據綁定、語義化標簽、依賴註入等等。本文我們主要和大家分享壹下會jQuery,該如何用AngularJS編程思想。

1. 我如何對客戶端web應用進行不同方式的架構和設計?它們之間最大的區別是什麽?(譯者註:指jQuery和Angular.js)

2. 有什麽是我不該做或者不該使用的;而又有什麽是我應該做或者應該使用的呢?

3. 有沒有壹些服務端的考量/約束呢?

我在尋找的就是壹個關於jQuery和Angular.js之間的詳細的比較。”

下面是來自 Josh David Miller 的最佳回答:

1. 絕不要先設計妳的頁面,然後用DOM操作去改變它

在jQuery中,妳會先設計壹個頁面,然後讓它變得動態化。這是因為jQuery是為了擴展而設計的,並在這個前提下變得越來越臃腫。

但是在Angular.js中, 妳必須從壹開始就在腦子裏掛著架構的弦。不要壹開始就想著“我有這樣壹個DOM,我想讓它做X”, 妳必須從妳要完成的目標開始思考,然後設計妳的應用, 最後才是設計妳的視圖。

2. 不要用 Angular.js 擴展 jQuery

類似地,不要壹開始就帶著這樣的想法:jQuery可以完成X,Y,Z,所以我只要在其上為模型和控制器添加Angular.js就行了。在起步階段這確實很容易勾引妳,這也是為什麽我總是推薦Angular.js新手根本不要使用jQuery,至少要在他們習慣了“angular 方式”之後。

我在這裏(譯者註:指stackoverflow)和郵件列表上看到過很多開發者,他們用150或者200行代碼的jQuery插件,然後利用壹堆讓人困惑的復雜的回調和$apply與Angular.js粘合起來建立這些詳盡的解決方案;最終確實可以跑起來! 但是其實這個問題在大多數情況下,我們可以用壹小段Angular.js代碼來重寫jQuery插件即可,而這種方式會讓壹切剎那間簡單明了可理解。

我覺得這類問題的底線是:當妳在解決問題時,首先利用“Angular.js思想”去做;如果妳不能想出壹個方案,那麽就在社區裏詢問;如果還是沒有簡單的解決方法,那麽再請隨意使用jQuery吧。但是註意,千萬別讓jqeury成為妳的拐杖,不然妳將永遠無法真正精通Angular.js。

3. 永遠根據架構去思考

首先妳要知道,單頁面結構也是應用。它不是網頁。所以我們需要有服務端開發者思想加上客戶端開發者思想。 我們必須考慮如何將我們的應用拆分為獨立,可擴展,可測試的組件。

那麽妳要怎麽做呢?妳如何做到利用“angualrjs思想”呢?這裏有壹些普遍的原則,與jQuery作為比照。

視圖是“正式記錄”

在jQuery中,我們通過編程方式來改變視圖。我們可以像下面這樣通過ul標簽來定義壹個下拉菜單:

<ul class="main-menu">

<li class="active">

<a href="#/home">Home</a>

</li>

<li>

<a href="#/menu1">Menu 1</a>

<ul>

<li><a href="#/sm1">Submenu 1</a></li>

<li><a href="#/sm2">Submenu 2</a></li>

<li><a href="#/sm3">Submenu 3</a></li>

</ul>

</li>

<li>

<a href="#/home">Menu 2</a>

</li>

</ul>在jQuery中,根據我們應用的邏輯,可以用類似下面的語句來激活它。

$('.main-menu').dropdownMenu();當我們只是看著視圖的時候,不會立刻看出它的功能。對於小應用而言,這樣是沒問題的。但是對於大型的應用,情況就壹下子變得令人困惑並且難以維護。

但是在Angular.js中,視圖是基於視圖的功能的正式記錄。我們的ul是像下面這樣聲明的:

<ul class="main-menu"dropdown-menu>

...

</ul>這兩者其實做了同樣的事情,但是在Angular.js的版本中,任何看到這個模板的人都知道將要發生什麽。不論何時,開發團隊裏有任何新的開發人員加入,她可以壹眼看出有壹個叫做dropdownMenu的指令作用在視圖上;她根本不需要憑直覺猜測或者研究下代碼才找到正確的答案。視圖本身就告訴我們將會發生什麽了。清晰多了。

angualrjs的新手經常會問這樣壹個問題: 我如何找到某壹類所有的鏈接並且給它們添加壹個指令呢?當看到我們回復的時候小夥伴都震驚了:壓根別去這樣做。但是勸妳不要這樣做的原因是,這樣做就像是壹半jQuery,壹半angulrjs,而這真心很糟。這裏的問題是,開發者想在angualrjs的情境中使用jQuery方式。而這絕對不會玩得轉。視圖是正式記錄。超出指令的範圍(這點下文會談論更多),妳絕不要去改變DOM。而且指令是應用在視圖中的,目的自然也壹目了然。

記住:不要先設計再修飾。妳必須先進行架構,然後再考慮設計。

數據綁定

這是Angular.js目前最酷的特性之壹,並且秒殺我前文提到的各種需要的DOM操作。不需要妳自己動手,Angular.js將自動更新妳的視圖有木有!

在jQuery裏, 我們響應事件並更新內容,大概是這個樣子:

$.ajax({

url:'/myEndpoint.json',

success:function( data, status ) {

$('ul#log').append('<li>Data Received!</li>');

}

});視圖則看上去是這樣的:

<ul class="messages"id="log">

</ul>除了關註點混合的問題,這裏同樣有之前提到的表征目的的問題。更重要的是,我們不得不手動引用並更新dom節點。並且如果我們想要刪除壹個日誌,我們不得不再次對dom編程操作。我們怎樣才能拋開dom來測試邏輯呢?還有,如果我們希望改變展現呢?

真是讓人淩亂。。

但是在Angular.js中,我們可以這樣做:

$pile('<a href="/hello" when-active>Hello</a>')( $scope );

$location.path('/not-matching');

expect( elm.hasClass('active') ).toBeFalsey();

$location.path('/hello');

expect( elm.hasClass('active') ).toBeTruthy();

}));我們運行測試,並確認它是失敗的。那麽我們來寫下我們的指令:

.directive( 'whenActive',function( $location ) {

return{

scope:true,

link:function( scope, element, attrs ) {

scope.$on('$routeChangeSuccess',function() {

if( $location.path() == element.attr('href') ) {

element.addClass('active');

}

else{

element.removeClass('active');

}

});

}

};

});現在我們的測試通過了,並且我們的菜單按照請求運行。我們的開發是叠代並且測試驅動的,太酷了哦!

5. 從概念上來看,指令不是打包的jQuery

妳會經常聽到“只在指令裏做dom操作”。這是必要的。請對它表示出尊重!

但是讓我們談點更深入的。。

壹些指令只是裝飾那些在視圖裏的已有的(想想ngClass),因此有時候就直接進行dom操作,基本上都能搞定。但是如果壹個指令像個“widget”並有壹個模板,

那它同樣要遵守關註點分離原則。也就是說,這個模板也應該與它在鏈接和控制器函數裏的實現保持最大的獨立。

Angular.js自帶著壹套工具讓這件事變得簡單; 使用ngClass我們能夠動態的更新類;ngBind允許雙向的數據綁定;ngShow和ngHide以編程的方式顯示或隱藏壹個元素;還有更多_包括我們自己寫的那些。換句話說, 我們可以不用DOM操作來實現所有的酷炫的事兒。 dom操作越少,指令越容易測試,它們也更容易樣式化,在未來它們也更容易改變,並且也變得更加可重用和可分發。

我看到很多Angular.js開發新手將指令當做放置壹堆jQuery的地方。換句話說, 他們認為:“既然我不能在控制器裏做dom操縱,那麽我就把這段代碼放到指令裏”。當然這看上去好多了,但是通常這仍然是錯的。

想壹下在第三節裏我們編寫的日誌記錄。即使我們將其放到壹個指令裏,我們仍然希望用“anggualjs方式”來做這件事情。這仍然沒有做任何dom操作!在很多情況下dom操作是必須的,但是這種情況其實比妳想的少得多!在妳在妳的應用中到處使用dmo操作之前,問問妳自己,這真的是必須的嗎。可能有更好的方法呢。

這裏用壹個簡單的例子來展示我們經常會看到的壹個模式。我們需要壹個切換按鈕。(註意:這個例子有那麽壹點人為設計的技巧並且有點_嗦,但是很多更復雜的情況其實也完全可以根據這個例子的方式來解決。)

.directive( 'myDirective',function() {

return{

template:'<a class="btn">Toggle me!</a>',

link:function( scope, element, attrs ) {

varon =false;

$(element).click(function() {

if( on ) {

$(element).removeClass('active');

}

else{

$(element).addClass('active');

}

on = !on;

});

}

};

});這裏有壹些錯誤。第壹,jQuery不是必須的。我們這裏做的壹切都不需要jQuery!第二, 即使是我們的頁面上已經有jQuery,也沒有理由壹定要在這裏使用它;我們可以簡單的使用angular.element,而且就算在壹個沒有jQuery的項目中我們的組件仍然可以工作。第三,即使我們假設為了讓這個指令工作,jQuery是必須的,如果jqury被加載,那麽jqLite(angler.element)壹定會使用jQuery。所以我們不需要使用$(譯者註:jQuery的壹個標識符號,是jQuery函數的別名)_我們可以使用angular.element。第四, 緊接第三點,jqLite元素不需要被包裹在$裏_傳遞給link函數的element已經是壹個jQuery元素!第五, 我上壹節已經提過的,為什麽我們要將模板混合進我們的邏輯呢?

這個指令可以更精簡的重寫(即時在更復雜的例子裏也壹樣):

.directive( 'myDirective',function() {

return{

scope:true,

template:'<a class="btn" ng-class="{active: on}" ng-click="toggle()">Toggle me!</a>',

link:function( scope, element, attrs ) {

scope.on =false;

scope.toggle =function() {

scope.on = !$scope.on;

};

}

};

});再次強調,模板的那些代碼都是在模板裏的,所以妳或者妳的使用者能夠很方便的將其換成壹個符合任何需要的樣式,同時邏輯不被改變。這就是重用性-贊!

當然,還有其它很多好處_比如測試 _ 這很容易! 不論什麽在模板中,指令的內部API絕不會被接觸,所以重構就變得容易。妳可以在不接觸指令的情況下隨意改變妳的模板。並且不論妳怎麽變,妳的測試仍可以通過。

耶!

所以如果指令不只是壹組jQuery風格的函數,那麽它們是什麽呢?指令其實就是html的擴展。如果html不能完成妳希望它做的壹些事情,妳就寫壹個指令來做,並且當它是html的壹部分來使用。

換句話說, 如果Angular.js壹下子無法完成手頭的工作,想想看妳的團隊是否能用ngClick、ngClass等來搞定它。

  • 上一篇:又壹款帶Web管理界面的內網穿透工具
  • 下一篇:誰能給我壹篇關於汽車塗裝車間實習的周記?
  • copyright 2024編程學習大全網