2013-12-09 112 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