7 AngularJS 的致命罪

下面列出了開發人員在使用 AngularJS 功能時經常犯的一些錯誤,一些經驗教訓和解決方案。

1.通過控制器操作 DOM

這是合法的,但必須避免。控制器是你定義依賴項,將資料繫結到檢視以及進一步構建業務邏輯的位置。你可以從技術上操作控制器中的 DOM,但是隻要你在應用程式的另一部分需要相同或類似的操作,就需要另一個控制器。所以這種方法的最佳實踐是建立一個包含所有操作的指令,並在整個應用程式中使用該指令。因此,控制器保持檢視完好無損並完成它的工作。在指令中,連結函式是操作 DOM 的最佳位置。它具有對範圍和元素的完全訪問許可權,因此使用指令時,你還可以利用可重用性。

link: function($scope, element, attrs) {
    //The best place to manipulate DOM
}

你可以通過多種方式訪問​​連結函式中的 DOM 元素,例如 element 引數,angular.element() 方法或純 Javascript。

2.翻譯中的資料繫結

AngularJS 以其雙向資料繫結而聞名。但是,有時你可能會遇到你的資料僅在指令內單向繫結。停在那裡,AngularJS 沒有錯,但可能是你。指令是一個有點危險的地方,因為涉及兒童範圍和孤立的範圍。假設你有一個包含一個轉換的以下指令

<my-dir>
    <my-transclusion>
    </my-transclusion>
</my-dir>

在我的轉換中,你有一些元素繫結到外部作用域中的資料。

<my-dir>
    <my-transclusion>
        <input ng-model="name">
    </my-transclusion>
</my-dir>

上面的程式碼無法正常工作。這裡,transclusion 建立了一個子範圍,你可以獲得 name 變數,但是你對這個變數所做的任何改變都會保留在那裡。因此,你可以真正將此變數作為 $ parent.name 訪問。但是,這種用法可能不是最好的做法。更好的方法是將變數包裝在物件中。例如,在控制器中,你可以建立:

$scope.data = {
    name: 'someName'
}

然後在轉換中,你可以通過’data’物件訪問此變數,並看到雙向繫結完美​​執行!

<input ng-model="data.name">

不僅在轉換中,而且在整個應用程式中,使用點分表示法是個好主意。

3.多個指令在一起

只要遵守規則,在同一元素中一起使用兩個指令實際上是合法的:兩個隔離的範圍不能存在於同一個元素上。一般來說,在建立新的自定義指令時,你可以分配一個隔離的範圍以便於引數傳遞。假設指令 myDirA 和 myDirB 具有 isoleted 範圍而 myDirC 沒有,則以下元素將是有效的:

<input my-dir-a my-dirc>

而以下元素將導致控制檯錯誤:

<input my-dir-a my-dir-b>

因此,必須明智地使用指令,並考慮範圍。

4.濫用$ emit

$ emit,$ broadcast 和$ on,這些工作在傳送者 - 接收者原則中。換句話說,它們是控制器之間的通訊手段。例如,以下行從控制器 A 發出’someEvent’,由相關控制器 B 捕獲。

$scope.$emit('someEvent', args);

並且以下行捕獲’someEvent'

$scope.$on('someEvent', function(){});

一切似乎都很完美但請記住,如果尚未呼叫控制器 B,則不會捕獲事件,這意味著必須呼叫發射器和接收器控制器才能使其工作。再說一遍,如果你不確定你肯定要使用$ emit,那麼構建服務似乎是一種更好的方法。

5.濫用$ scope。$ watch

$ scope。$ watch 用於觀察變數變化。每當變數發生變化時,都會呼叫此方法。但是,一個常見的錯誤就是更改$ scope 內的變數。$ watch。這會在某些時候導致不一致和無限$ digest 迴圈。

$scope.$watch('myCtrl.myVariable', function(newVal) {
    this.myVariable++;
});

所以在上面的函式中,確保你對 myVariable 和 newVal 沒有任何操作。

6.將方法繫結到檢視

這是最致命的罪行之一。AngularJS 具有雙向繫結功能,每當更改內容時,檢視都會多次更新。因此,如果將方法繫結到檢視的屬性,則該方法可能會被呼叫一百次,這也會讓你在除錯期間發瘋。但是,只有一些為方法繫結而構建的屬性,例如 ng-click,ng-blur,ng-on-change 等,它們將方法視為 paremeter。例如,假設你的標記中包含以下檢視:

<input ng-disabled="myCtrl.isDisabled()" ng-model="myCtrl.name">

在這裡,你可以通過 isDisabled 方法檢查檢視的禁用狀態。在控制器 myCtrl 中,你有:

vm.isDisabled = function(){
    if(someCondition)
        return true;
    else
        return false;
}

從理論上講,這似乎是正確的,但從技術上講,這會導致過載,因為該方法將執行無數次。為了解決這個問題,你應該繫結一個變數。在你的控制器中,必須存在以下變數:

vm.isDisabled

你可以在啟用控制器時再次啟動此變數

if(someCondition)
    vm.isDisabled = true
else
    vm.isDisabled = false

如果條件不穩定,你可以將其繫結到另一個事件。然後你應該將這個變數繫結到檢視:

<input ng-disabled="myCtrl.isDisabled" ng-model="myCtrl.name">

現在,檢視的所有屬性都具有他們所期望的內容,並且方法僅在需要時執行。

7.不使用 Angular 的功能

AngularJS 通過一些功能提供了極大的便利,不僅簡化了程式碼,而且提高了效率。其中一些功能如下:

  1. angular.forEach for the loops(注意,你不能破壞它,你只能防止進入身體,所以在這裡考慮效能。)
  2. **** DOM 選擇器的 angular.element
  3. angular.copy :當你不應該修改主物件時使用它
  4. 表格驗證已經很棒了。使用髒,原始,觸控,有效,必需等。
  5. 除了 Chrome 偵錯程式,還可以使用遠端除錯進行移動開發。
  6. 並確保你使用 Batarang 。這是一個免費的 Chrome 擴充套件程式,你可以輕鬆檢查範圍