最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

jQuery和AngularJS的區(qū)別淺析

 更新時間:2015年01月29日 08:59:39   投稿:junjie  
這篇文章主要介紹了jQuery和AngularJS的區(qū)別淺析,本文著重講解一個熟悉jQuery開的程序員如何應(yīng)對AngularJS中的一些編程思想的轉(zhuǎn)變,需要的朋友可以參考下

最近一直在研究angularjs,最大的感受就是它和之前的jQuery以及基于jQuery的各種庫設(shè)計理念完全不同,如果不能認(rèn)識到這點(diǎn)而對于之前做jQuery開發(fā)的程序員,去直接學(xué)習(xí)angularjs的話,很可能學(xué)了很久還不知道這個東西能用來干什么以及怎么使用,怎么和UI進(jìn)行結(jié)合等問題,在stackoverflow上找到一篇關(guān)于這方面的文章,閱讀之后頗有收獲,在此基礎(chǔ)上將它譯成中文,以求拋磚引玉大家一同學(xué)習(xí)。

原問題:假如我熟悉利用jQuery去開發(fā)客戶端應(yīng)用,那么我怎么上手angularjs,能否描述下所需要的模式轉(zhuǎn)變,下面這些問題能夠幫助你給出一個回答:

1.在設(shè)計客戶端web應(yīng)用的時候有什么區(qū)別,最大的區(qū)別是什么?

2.我應(yīng)該停止使用哪些技術(shù),同時又使用哪些技術(shù)作為替代?

3.是否存在服務(wù)端需要考慮的東西或者說一些限制呢?

回答:

1.不要首先設(shè)計好你的頁面,然后再通過DOM操作去修改它

在jQuery中,你首先設(shè)計了一個page,然后再去動態(tài)修改它的內(nèi)容,這是因為jQuery被設(shè)計用來進(jìn)行擴(kuò)展并在這個前提下大幅度地增加和修改內(nèi)容,但是在angularjs中,你必須在心中先設(shè)計好你的架構(gòu),

從一開始,你就要摒棄“我擁有一個DOM元素并且想讓它去做某件事”,代之為“我需要完成什么任務(wù),然后接著設(shè)計你的應(yīng)用,最后再去設(shè)計你的視圖view層”。

2.不要使用angularjs去擴(kuò)展jQuery

相應(yīng)地,不要存在說讓jQuery去干某些事情,然后在此基礎(chǔ)上添加angularjs的功能讓它去管理model以及controller的想法。所以我一般不推薦AngularJS開發(fā)新手同時使用jQuery,至少在他們還沒有適應(yīng)AngularJS的開發(fā)模式之前不會去推薦這樣做,但是當(dāng)你真正開始適應(yīng)angularjs 的方式之后,你會發(fā)覺這是一件很誘人的事情。

我曾經(jīng)看到過很多開發(fā)者采用將150到200行代碼的jQuery插件利用angularjs的回調(diào)以及$apply方法封裝起來,這種方式使得代碼看起來極其復(fù)雜,但是實際上他們讓這些插件跑起來了!問題在于,在大部分情況下jQuery插件能夠用angularjs進(jìn)行重寫,并且可能只會使用很少量的代碼,同時這種重寫使得代碼很直觀且易于理解,這顯然好過于將jQuery代碼直接做封裝。

所以最后說,當(dāng)你遇見問題的時候,首先要以angularjs的思維進(jìn)行思考,如果找不到解決方案,可以求助于社區(qū),如果說沒有人能夠給出一個簡單的方案,那么才考慮使用jQuery,不要讓jQuery成為你的拐杖,否則你永遠(yuǎn)掌握不了AngularJS。

3.要以架構(gòu)為中心進(jìn)行思考

首先你要知道單頁應(yīng)用屬于web應(yīng)用,它們不是傳統(tǒng)的多網(wǎng)頁網(wǎng)站,所以我們要同時作為一個服務(wù)端和客戶端開發(fā)者的思維進(jìn)行思考,我們需要思考如何將我們的應(yīng)用分為獨(dú)立的,可擴(kuò)展的以及可測試的部分。

那么接下來我們?nèi)绾尾捎肁ngularJS思維去工作呢,以下是一些將其與jQuery對比之后的基本準(zhǔn)則:

以下是某個應(yīng)用的視圖層:

在jQuery中,我們動態(tài)地去修改這個視圖,我們使用ul去定義一個dropdown menu

復(fù)制代碼 代碼如下:

<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中,我們采用如下邏輯使用這個dropdownMenu

復(fù)制代碼 代碼如下:

$('.main-menu').dropdownMenu();

讓我們回頭看看這個view,你會發(fā)現(xiàn)它的功能并不是很直白,對于小型應(yīng)用來講,這樣是可以的,但是對于大型應(yīng)用來講,這種方式會讓人費(fèi)解并且難以維護(hù);

在angularjs中,這個視圖實際上是一項基于視圖的功能,我們可以這樣來定義ul

復(fù)制代碼 代碼如下:

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

這兩種方式實際上做了同樣的事情,但是在AngularJS方式下任何人看到這個視圖模板就知道接下來要干什么。無論何時當(dāng)一個新成員加入開發(fā)團(tuán)隊之后他都能夠看到這里并發(fā)現(xiàn)這里有一個叫做dropdownMenu的指令去操作view,他不需要去猜想正確的答案或者審查其他的代碼,這個視圖就直接告訴我們它要做什么,相比于jQuery,它更為簡潔。

常常有些AngularJS新手問這樣的問題:我怎么才能找到某個確切類型的所有l(wèi)ink并在此基礎(chǔ)上添加一個directive,但是當(dāng)我們回答了“你不應(yīng)該這樣去做,你這是一種半jQuery半angularjs的想法”時,他們會覺得很吃驚。

問題在于他們試圖在AngularJS背景下用jQuery去做某件事,這通常不是一種好的方式,在指令之外你不需要去做任何dom操作,而指令是直接內(nèi)添加在視圖上的,所以意圖已經(jīng)很明顯了。記住,不要先設(shè)計好之后再去修改,而是先有架構(gòu)然后在這個框架下再去設(shè)計。

數(shù)據(jù)綁定

這是到目前為止AngularJS最令人矚目的特性了,在數(shù)據(jù)綁定方面它舍棄了對DOM的操作方式,而這一切都是由AngularJS來自動更新視圖,你不必寫操作dom的代碼,在jQuery中,我們常常按照以下方式響應(yīng)事件并修改視圖:

復(fù)制代碼 代碼如下:

$.ajax({
  url: '/myEndpoint.json',
  success: function ( data, status ) {
    $('ul#log').append('<li>Data Received!</li>');
  }
});

相對于這樣一個視圖

復(fù)制代碼 代碼如下:

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

除了混雜的問題之外,我們還存在我之前提到的如何表明自己意圖的問題。但是更為重要的是,我們必須人工手動去引用并更新這個DOM節(jié)點(diǎn),如果我們想刪除其中一條,那么必須以編程方式去操作那個DOM元素,那么在這種情況下我們怎么去測試DOM節(jié)點(diǎn)之外的邏輯呢,亦或者我們想改變展示方式呢?

以上代碼顯得凌亂又脆弱,但是在AngularJS中,我們可以這樣做:

復(fù)制代碼 代碼如下:

$http( '/myEndpoint.json' ).then( function ( response ) {
    $scope.log.push( { msg: 'Data Received!' } );
});

我們的視圖應(yīng)該像下面這樣

復(fù)制代碼 代碼如下:

<ul class="messages">
    <li ng-repeat="entry in log">{{ entry.msg }}</li>
</ul>

在那種情況下,我們的視圖也可以這樣

復(fù)制代碼 代碼如下:

<div class="messages">
    <div class="alert" ng-repeat="entry in log">
        {{ entry.msg }}
    </div>
</div>

現(xiàn)在我們不使用ul,而是使用Bootstrap的彈出框,但是我們不用修改controller中的代碼,更為重要的是,不管是數(shù)據(jù)如何修改,視圖層也會自動隨之發(fā)生變化,非常簡潔!

盡管我這里不會做演示,但是你需要知道數(shù)據(jù)綁定是雙向的,你可以編輯數(shù)據(jù)通過添加指令<input ng-model="entry.msg" />,此外還有很多其他的令人興奮的地方。

區(qū)別model層

在jQuery中,DOM類似于一種model,但是在AngularJS中,我們擁有不同于jQuery中的model層以便我們可以以任何我們想要的方式去管理它,它是完全獨(dú)立于視圖之外的。這種方式是有助于我們進(jìn)行數(shù)據(jù)綁定并且可以保持對分離的關(guān)注,而且可以具備更好的可測試性。

關(guān)注點(diǎn)分離

以上所講都和這個總體的話題相關(guān):讓你關(guān)注分離,你的視圖層顯示記錄,你的model層代表數(shù)據(jù),你還有個服務(wù)層用來執(zhí)行這些可復(fù)用的任務(wù)。你使用directive來執(zhí)行dom操作并擴(kuò)展你的視圖,并將它和controller連接起來,這也就是我在其他方面提到的有關(guān)于增強(qiáng)可測試性的原因。

依賴注入

幫助我們解決關(guān)注點(diǎn)分離的是依賴注入(DI),如果你是一個服務(wù)端開發(fā)者(Java或者PHP),你可能已經(jīng)很熟悉這個概念了,但是如果你是從事客戶端開發(fā)的,你會覺得這個概念可能有些多余和純屬追求時髦,但是實際上不是這樣。

從廣義的角度講,DI意味著你可以自由地聲明組件然后從這些組件中進(jìn)行實例化,這是理所當(dāng)然的。你不必知道加載順序,文件位置等諸如此類的事情,這種魔力不是能夠立即看到,但是我會給出一個例子:測試。

我們說在應(yīng)用中,我們需要一個依賴于應(yīng)用狀態(tài)和本地存儲的服務(wù)用來通過一個rest API來執(zhí)行服務(wù)端存儲,當(dāng)我們測試我們的controller時,我們不必和服務(wù)端進(jìn)行通信,畢竟只是在測試controller而已。我們僅添加一個與我們最初組件相同的mock服務(wù),注入器能夠確保我們的controller獲得一個虛擬的服務(wù),controller自身不必也不需要了解這種差異。

那么說說測試吧。

4.以測試驅(qū)動的開發(fā)

這部分是一個架構(gòu)的第三部分,但是他是很重要的,以至于我需要將它放在最重要的位置。

在我們所有見過的,用過的以及寫過的jQuery插件中,有多少具有一套測試組件呢?其實并不多,這是因為jQuery在測試上不易控制,但是AngularJS卻與此不同。

在jQuery中,測試的唯一方法是使用一個demo頁去創(chuàng)建一個獨(dú)立組件來使得我們的測試可以執(zhí)行dom操作。我們接下來我們必須開發(fā)一個獨(dú)立的組件然后將它集成到我們的應(yīng)用中來,這是多不方便啊!在很多情況下,當(dāng)我們使用jQuery開發(fā)實際上是做了很多重復(fù)開發(fā)而不是以測試驅(qū)動的開發(fā),這又能怪我們嗎?

但是在AngularJS中我們可以關(guān)注分離點(diǎn),所以我們可以做一些測試驅(qū)動的開發(fā)。例如,我們有一個directive用來說明在menu中我們的當(dāng)前路徑,我們可以在視圖中這樣聲明:

復(fù)制代碼 代碼如下:

<a href="/hello" when-active>Hello</a>

好了,現(xiàn)在我們可以寫一個測試用來測試這個不存在的指令when-active了

復(fù)制代碼 代碼如下:

it( 'should add "active" when the route changes', inject(function() {
    var elm = $compile( '<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();
}));

我們直接run測試用例,你會發(fā)現(xiàn)是失敗的,這時候需要創(chuàng)建這個指令,如下:

復(fù)制代碼 代碼如下:

.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' );
                }
            });
        }
    };
});


再次run這個測試用例,你會發(fā)現(xiàn)通過了并且菜單如請求的樣子顯示,我們的開發(fā)是兼有反復(fù)性和可測試性,非??岚?!

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

你常常聽說,dom操作只能在指令中,這是必須的,你必須嚴(yán)肅對待。

讓我們深入討論,

某些指令僅僅是裝飾我們的視圖(例如ngClass),因此有時候直接操作dom是可以的,但是當(dāng)一個指令類似于一個小物件并且擁有自己的模板,那么它應(yīng)該當(dāng)做一個分離的關(guān)注點(diǎn),這就是說,它的模板需要和link中的執(zhí)行邏輯以及其他controller函數(shù)分離開。

AngularJS擁有一整套的工具可以是這種分離更簡單,使用ngClass指令,我們可以動態(tài)地更新class,使用ngBind我們可以進(jìn)行雙向數(shù)據(jù)綁定,使用ngShow和ngHide 我們

可以采用編程的形式顯示和隱藏一個元素,也包括我們自己寫的很多指令。換句話說,我們可以不用Dom操作而完成所有工作,dom操作越少,指令越容易測試,越容易指定他們的style屬性,就越容易在將來改變他們,那么他們就越容易復(fù)用和分發(fā)。

我看過很多AngularJS新手使用指令封裝一大串 jQuery代碼,換句話說,既然我不能在controller里面進(jìn)行dom操作,那么我可以將他放在指令中,雖然這相對于直接操作dom好很多,但是任然是錯誤的。

看看我們在上面的記錄,即使我們將其放在一個指令中,我們?nèi)稳恍枰訟ngular的方式去操作它,這種方式不執(zhí)行dom操作!在很多時候dom操作是需要的,但是這種情況比你想的要少得多。當(dāng)我們需要做dom操作的時候先問問自己這里是否必須這樣做,這才是一種更好的方式。

下面是一個簡單的例子用來表明我常常見到的一種模式,我們需要I一個可切換的button:

復(fù)制代碼 代碼如下:

.directive( 'myDirective', function () {
    return {
        template: '<a class="btn">Toggle me!</a>',
        link: function ( scope, element, attrs ) {
            var on = false;
 
            $(element).click( function () {
                on = !on;
                $(element).toggleClass('active', on);
            });
        }
    };
});

在以上例子中存在以下錯誤:

1.首先,jQuery是不必要的,這里的工作完全不需要jQuery!

2.第二,即使我們已經(jīng)在頁面中引入了jquery,但是我們沒有理由去使用它,我們可以使用angular.element而我們的組件也能夠運(yùn)行,即使這個項目中沒有引入jQuery。

3.第三,假設(shè)jquery是需要的在我們的指令中,我們可以使用jqLite去進(jìn)行替代,只要引入jQuery即可,所以我們不必使用$而是使用angular.element;

4.第四,和第三點(diǎn)聯(lián)系很緊密,jqLite元素不必使用$包裹起來,element元素傳遞到link函數(shù)中已經(jīng)是一個jQuery對象了;

5.第五,我們之前已經(jīng)說過,為什么不將我們的模板和邏輯混合起來呢?

以上指令可以按照如下方式來重寫,即使在最復(fù)雜的情況下看起來也如此簡單。

復(fù)制代碼 代碼如下:

.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;
            };
        }
    };
});

模板元素是在 template屬性中,你可以很容易替換掉它的style,而邏輯根本不用發(fā)生變化,達(dá)到了完全復(fù)用!

還有其他的好處,比如測試起來很簡單,不管模板里面是什么,指令A(yù)PI都不會發(fā)生改變,所以重構(gòu)它很簡單。你可以隨意多次改變你的模板而不用改變指令,無論你怎么改變,你的測試總能通過!

所以說指令不是一堆jQuery代碼的集合,比如函數(shù)等,而是HTML代碼的擴(kuò)展,如果HTML代碼不能實現(xiàn)你需要的功能,你可以寫一個指令去實現(xiàn)它,然后像使用HTML那樣去使用它。

以另外一種方式講,AngularJS如果不做額外的事情,想想我們怎么能夠使用ngClick,ngClass指令呢?

總結(jié)

不要總使用jquery ,甚至不要去引用它,它會阻止你前進(jìn),當(dāng)我們回到這個問題—你知道你怎么在AngularJS中以jquery方式解決問題,但是當(dāng)你使用諸如$等選擇器時,你要想想它們實際上是禁錮了AngularJS,如果你不知道怎么不用jQuery實現(xiàn),那么去請教別人,一次一次去問,最好的方式是不需要使用jQuery,使用jQuery只會導(dǎo)致你的工作量提升。

相關(guān)文章

  • AngularJS中的DOM操作用法分析

    AngularJS中的DOM操作用法分析

    這篇文章主要介紹了AngularJS中的DOM操作,較為詳細(xì)的分析了AngularJS針對DOM操作的原理、實現(xiàn)技巧與相關(guān)注意事項,需要的朋友可以參考下
    2016-11-11
  • angularJS自定義directive之帶參方法傳遞詳解

    angularJS自定義directive之帶參方法傳遞詳解

    今天小編就為大家分享一篇angularJS自定義directive之帶參方法傳遞詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • AngularJS實現(xiàn)表單驗證功能

    AngularJS實現(xiàn)表單驗證功能

    這篇文章主要為大家詳細(xì)介紹了AngularJS實現(xiàn)表單驗證功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • Angular @HostBinding()和@HostListener()用法

    Angular @HostBinding()和@HostListener()用法

    本篇文章主要介紹了Angular @HostBinding()和@HostListener()用法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • angular6 利用 ngContentOutlet 實現(xiàn)組件位置交換(重排)

    angular6 利用 ngContentOutlet 實現(xiàn)組件位置交換(重排)

    這篇文章主要介紹了angular6 利用 ngContentOutlet 實現(xiàn)組件位置交換(重排),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • Angular異步變同步處理方法

    Angular異步變同步處理方法

    今天小編就為大家分享一篇Angular異步變同步處理方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • AngularJS入門教程之ng-checked 指令詳解

    AngularJS入門教程之ng-checked 指令詳解

    本文主要講解AngularJS ng-checked 指令,在這整理ng-checked 指令的基礎(chǔ)知識,并附代碼實例,有需要的小伙伴可以參考下
    2016-08-08
  • Angular2 PrimeNG分頁模塊學(xué)習(xí)

    Angular2 PrimeNG分頁模塊學(xué)習(xí)

    這篇文章主要為大家詳細(xì)介紹了Angular2 PrimeNG分頁模塊學(xué)習(xí)教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • angular4實現(xiàn)帶搜索的下拉框

    angular4實現(xiàn)帶搜索的下拉框

    這篇文章主要為大家詳細(xì)介紹了angular4實現(xiàn)帶搜索的下拉框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • angular.js分頁代碼的實例

    angular.js分頁代碼的實例

    本文用實例詳細(xì)給大家展示了angular.js分頁代碼,代碼很詳細(xì),感興趣的小伙伴們可以參考一下
    2016-07-07

最新評論

桂阳县| 龙门县| 留坝县| 武清区| 应用必备| 冷水江市| 巨野县| 崇信县| 武穴市| 五大连池市| 兰西县| 玉田县| 霍林郭勒市| 松原市| 贵州省| 香格里拉县| 新和县| 韶关市| 开鲁县| 汝阳县| 洛扎县| 庆安县| 龙井市| 海门市| 天长市| 陈巴尔虎旗| 五莲县| 托克托县| 日喀则市| 昆山市| 油尖旺区| 蒲城县| 汨罗市| 从江县| 鹤庆县| 博乐市| 白玉县| 锡林郭勒盟| 永靖县| 道真| 义马市|