2014-07-15 82 views
12

我對角度相當陌生,並試圖真正學會如何組織代碼,以便將來的同事能夠快速找到解決方法。AngularJS:指令與控制器 - 什麼邏輯放在哪裏?

我知道的一個規則是「如果它操縱DOM,把它放入一個指令」,我遵守。

但是仍然有些時候我不確定把我的方法放在哪裏,因爲我可以把它們放到主應用程序控制器中,放入一個作爲控制器提供的控制器中,或者甚至在指令中的「控制器」選項該指令(選項「鏈接」)。

有了過濾器和服務,我很清楚,但是對於控制器和指令,這條線變得非常模糊。 我已經意識到,即使有一個小應用程序,我在這裏和那裏傳播了一些代碼,它已經令人困惑,即使對我自己也是如此。所以我想要更好地組織我的代碼來獲得一些Tipps。

所以我想我的主要問題是:
1)有一個很好的經驗法則知道什麼代碼放在哪裏?

或者如果這太抽象這裏有一些例子:
2)我有一個指令,只在我的應用程序中使用模板。當我點擊元素時會發生某些事情。我已經知道它更喜歡使用ng-click指令來綁定鏈接函數中的點擊事件。
但是我應該在哪裏定義在ng-click中提供的方法?

  • A)應用程序的主要控制器。 B)指令的「鏈接」功能。
  • C)向指令添加一個控制器(使用「控制器」選項)並在那裏定義它。

3)如果我打算在其他地方重新使用指令,2)的答案是否會有所不同?

4)不同的情景:
我有一個按鈕,點擊並拖動它應該移到一個完全無關的元素時。
我......

  • A)應該創建一個指令,並根據通過屬性影響模板&行爲?
  • B)創建兩個指令(一個用於句柄,一個用於目標元素)
    如果是這樣,它又提出了將方法放在哪裏來處理拖動的問題?

注:
我知道答案可能有點依賴於個人的意見,但我還挺希望有一些「規則」,或者,我可以爲未來恪守「做正確的方式」發展。 爲簡明起見,我沒有包含任何代碼。 如果需要答案,我很樂意提供。

謝謝你的時間。

+0

我一直認爲僞指令的jQuery插件類似於jQuery用戶界面上發現的相當。例如,您可能有一個特殊輸入類型,如日期或時間。或者,也許你會創建一個國家和/或語言選擇器。它們應該是接受參數然後發出事件,觸發回調或更新模型的黑盒子。 –

回答

0

1)有一個很好的經驗法則,知道什麼代碼放在哪裏?

很多東西在這裏玩;我不確定是否有'指令與控制器'的戰鬥正在進行。他們對我來說似乎不同。如果你不知道,指令可以有自己的控制器。

我將指令視爲包含HTML(視圖)和JavaScript代碼(控制器)的單個特定封裝代碼集。當我想將某些東西作爲「封裝」組件使用時,我使用指令。

如果我只是有一點JavaScript代碼,我想重用;我將把一個AngularJS服務放到一個沒有任何HTML的JavaScript代碼集合中。

我有一個指令,只在我的應用程序中使用模板。 當我點擊元素時會發生某些事情。我已經知道 它優先使用ng-click指令來綁定鏈接函數內的點擊事件 。但是我應該在哪裏定義ng-click提供的方法 ?

我將處理程序定義爲指令的隔離範圍的一部分;如下所示:

scope: 
{    
    onButtonClick: '&onButtonClick' 
} 

將默認行爲定義爲指令鏈接或控制器的一部分。

link: function ($scope, element, attrs) { 
    $scope.myDefaultButtonClick = function(){ 
    // do stuff 
    } 

     this.onInit = function(){ 
      if(!$scope.onButtonClick){ 
       $scope.onButtonClick = $scope.myDefaultButtonClick; 
      } 
     } 
     this.onInit(); 
} 

在您的JavaScript中;您可以調用傳入的參數作爲參數:

$scope.onButtonClick(); 

而且您可以在HTML模板中執行相同的操作。

<img src="button.png" ng-click="onButtonClick()"> 

3)請問答案2)是不同的,如果我打算在其他地方重用 指令?

如果我不打算重用;我可能不會使用指令。

I have a Button and when clicked and dragged it should move a completely unrelated Element. 
Should I... 

    A) Create one directive and influence template & behavior based on a passed attribute? 
    B) Create two directives (one for the handle, one for the target Element) 
    If so, it again poses the question of where to put the methods to handle the dragging? 

我可能會選擇A項;將需要操作的元素作爲參數傳遞給指令。但是,這取決於我關心這個功能的可用性。

我說的一切都應該被認爲是主觀的。

+0

謝謝你的回答。不幸的是,我可能在我的問題上太不清楚了。我知道指令可以有自己的控制器,但這是我的問題的一部分。我如何決定哪些方法來定義在哪裏?在你的例子中2)你在鏈接函數中定義它。但它也可能在應用程序控制器或指令個人控制器中。我如何決定? –

+0

@JanPaepke在我的例子中;我在鏈接中定義了一個** DEFAULT **方法[它也可以在指令的控制器中]。但是,它可以很容易地用您希望使用API​​的任何功能來替換。創建指令時;我將所有指令特定的代碼放入指令中。但是,這確實是一個基於你想要做什麼的判斷。 – JeffryHouser

7

首先,很好的問題。我認爲每個新開發角度的開發人員都在與所有給定組件(控制器,指令,服務,過濾器等)之間的差異鬥爭。

讓我們先從基本的正式定義:

指令是一個DOM元素,告訴AngularJS的HTML編譯器到指定的行爲附加到DOM元素上的標記。

而在另一方面

控制器是用來增加的角度範圍

定義的行爲JavaScript構造函數確實引導我們通過一些規則的,拇指。

因此,對於你的問題上面:

  1. 簡單地說,我們的用戶控制器以 與所有偉大的能力控制器帶來 HTML模板(雙向管理的區域(範圍) )我們 當我們希望操縱現有的HTML元素或 時使用指令在大多數情況下 - 當我們考慮重新使用時自定義出自己的 這個元素。
  2. 這取決於ng-click應該做什麼的上下文。假設你有一個數字輸入的自定義指令,這個數字輸入具有你在指令配置中定義的自定義設計和行爲。你可以用ng-click的形式使用它,以便彈出一個帶有可選值的模式,並在應用程序中的不同位置使用它,而ng-click將做其他事情。在這種情況下,該功能需要成爲scope.fucntion。但讓我們說,位置和每個其他將完全相同,這將功能的指令範圍。
  3. 回答上面:)
  4. 您的每個選項都可以做到這一點,在這個地方,「意見」需要接受並且存在較少的經驗法則。爲什麼?因爲每種方式都有其優點和缺點,所以兩種方式都可以工作我可以在該場景中找到的經驗法則是,如果兩個元素都是指令模板的一部分,我希望「行爲可見」(拖動函數)成爲指令範圍的一部分。

好運

+0

謝謝!這清除了一些東西(特別是你的正式定義)。儘管理解你的答案,但我無法理解。你能進一步闡述一下嗎? –

+0

嘿@JanPaepke,我想要抽象的是,你處理你的困境的方式關於控制器指令(答案#1中解釋)之間的不同之處是處理問題#2中的困境的方式。如果指令行爲在整個應用程序中都是相同的行爲,則將行爲作爲指令的一部分。但是,如果behviour不同,則使用控制器作用域,定義作用域函數並在ng-click中使用它。再次表示 - 兩種方式都可以完成這項工作,但這是正確的做法。 –

+0

對我來說,這仍然不是100%清楚,但我會繼續工作,並回到這個。也許我只是缺乏一些經驗來理解它。 –