2013-12-09 152 views
8

我是相當新的角度JS和我發現它陡峭的學習曲線,給我的感覺,我真的錯過了點,在這裏,但這裏有雲:動態添加角指令

我想一個指令添加到我的來自控制器的頁面。所以我想如果我添加指令標籤到頁面,指令和相關的控制器/模板等與它一起被添加。在閱讀了$ compile方法之後,我認爲這會被用來將這個指令綁定到它新創建的標籤。這部分是在下面註釋的,但有或沒有這個,我需要登錄這個詞出現,其控制器來控制它?

當加載時指令標籤在頁面上時,我可以找到很多類似於Web的類似示例,並且可以使這些工作正常,所以這就是使得認爲它與$ compile方法相關的原因 - 我錯過了什麼?

HTML:

<div ng-app="application" ng-controller="myController"></div> 

JS:

​​

上面的代碼也在於此:http://jsfiddle.net/d5n6L/7/

+0

IM也很肯定我不應該從我的控制器中添加DOM元素,如此讚賞過的任何建議! – alfonsob

+0

如果你還沒有already..read此:** [我如何「認爲AngularJS」如果我有一個jQuery的背景(http://stackoverflow.com/questions/14994391/how-do-i-認爲,在-angularjs-IF-I-有-A-jQuery的背景)** – charlietfl

+0

輝煌charlietfl,正是我所需要的! – alfonsob

回答

8

你真的不應該動態地將元素添加到頁面角。包括我自己在內的許多來自jQuery背景的人都假設我們可以繼續這種做法,只是在我們需要的時候向頁面添加內容。

但是,使用Angular時,邏輯應該在標記中全部可見。那是什麼意思?在你的情況下,無論如何你都應該有指令,然後用ng-showng-hideng-class來控制它的可見性。

所以,這樣的事情將是最好的:

<login ng-show="showLogin"></login> 

然後你就可以用你的指令,因爲你編程。

請注意,您還可以定義一個內聯控制器(將指定的controller屬性分配給一個依賴關係數組和一個函數)。這將所有相關的代碼保存在同一個地方。

例如,

angular.module('directives', []) 
    .directive('login', function($compile) { 
     return { 
      restrict: 'E', 
      controller: ['$scope', function($scope) { 

       function showLoginDirective() { 
        $scope.showLogin = true; 

       }; 

       showLoginDirective(); 
       } 
      ], 
      template: '<div>login</div>', 
      link: function(scope, element, attrs) { 
       //$compile(element.contents())(scope.$new); 
       console.log('should i not have a div containing login controlled by loginController at this point?'); 
      } 
     }; 
}); 
+0

非常相似的答案礦:) – eddiec

+0

感謝您的回答,更重要的解釋,是的,我來自何方,除其他事項外,一個jQuery的背景。我有點看到角的力量,但正如我所說,我發現它是一個陡峭的斜坡! – alfonsob

+0

對於我來說,最重要的一點是,通過查看標記,您應該能夠看到正在發生的一切。當事情出現,消失時,禁用時會發生什麼,當你點擊它們時會發生什麼,等等。你可以使用Angular指令和自定義作用域方法/屬性來做所有事情,並且知道發生了什麼,而無需查看任何代碼。在jQuery中,您需要查看代碼才能看到發生了什麼。 – jraede

4

而不是從你的控制器內的動態編譯我建議你使用NG-如果到聲明性地表示DOM上應該存在哪些DOM元素。

HTML

<div ng-app="application" ng-controller="myController"> 
    <div ng-if="showLogin" login></div> 
</div> 

JS

var myApp = angular.module('application', []); 

myApp.controller('myController', ['$scope', function($scope) { 

     function showLoginDirective() { 
      $scope.showLogin = true; 
     }; 

     showLoginDirective(); 
    } 
]); 

angular.module('directives', []) 
    .directive('login', function($compile) { 
     return { 
      restrict: 'E', 
      controller: 'LoginController', 
      template: '<div>login</div>', 
      link: function(scope, element, attrs) { 
       //$compile(element.contents())(scope.$new); 
       console.log('should i not have a div containing login controlled by loginController at this point?'); 
      } 
     }; 
}); 
+0

哇,偉大的思想認爲我看得見。 ;-) – jraede

+0

同上,謝謝eddiec! – alfonsob

3

我想一個指令從控制器添加到我的網頁。

您應該能夠在$ scope中定義一個布爾變量來決定是否顯示登錄。

$scope.loginShouldBeShowing = false; 
$scope.showLogin = function() { 
    $scope.loginShouldBeShowing = true; 
}; 

如果這個變量設置爲true

<login ng-if="loginShouldBeShowing"></login> 

您可以在修改的jsfiddle在看到這個然後,您可以在模板中使用,與ngIf指令,只顯示登錄模板

http://jsfiddle.net/jK9zr/2/

我還添加了一個按鈕,這樣你就可以在該link函數只AFTE後運行控制檯中看到R您按下按鈕,loginShouldBeShowing被設置爲true

我可以找到很多的網絡上類似的例子,當指令標籤是在加載時頁面上,並能得到那些做工精細,所以這是什麼使它認爲它與$編譯方法有關

從我的理解和以前的使用,通常在模板中包含指令僅用於某些情況下,即當某些$ scope變量是設置爲某些值,使用ngIf或ngSwitch或ngShow。我認爲,如果您試圖編譯模板的每一部分,可能會或可能不會在任何時候使用,那麼事情很快就會變得非常混亂。雖然我只在AngularJS相對初學者,所以到目前爲止,我只過使用$評估定製指令屬性時,編譯,所以

<login after-login="doThisFunction()"></login> 
然後

可能需要使用$編譯在調用doThisFunction()適當的點。

作爲一個小邊欄,你變量的名稱有點告知控制器,您關注的是正在發生的事情的模板。在控制器中保持某種模型/業務「狀態」更爲常見,然後在模板中顯示相應的內容。所以,你可能會在控制器:

$scope.loginState = 'loggedOut'; 

然後在模板:

<login ng-if="loginState == 'loggedOut'"></login> 

編輯:我也注意到,在登錄指令是在不同的模塊,應用程序的其餘部分。我懷疑這導致了問題,所以我在JSFiddle中修改了這個方面,所以只有一個模塊。

編輯:我覺得我很困惑$之間編譯和上面$解析,所以我想覈對一下我使用$編譯文檔/其他來源。

+0

再次感謝米哈爾,你對事物的解釋已經幫助我多了一點點。我發現很多角度的例子/文檔都發現錯誤地解釋了這些基礎知識 - 堆疊岩石! – alfonsob

+0

沒問題,儘管我認爲我已經在$ compile和$ parse之間產生了混淆,所以不要一定要這麼做! –

+0

也許這比ng-show更好,如果你不希望指令被編譯 – Tropicalista