我对角度JS相当新,并且发现它是一个陡峭的学习曲线,我觉得我真的错过了这里的重点但是这里有:
我想从控制器向我的页面添加一个指令。所以我想如果我将指令标签添加到页面,指令和相关的控制器/模板等都会添加它。在阅读了$ compile方法之后,我认为这将用于将此指令绑定到其新创建的标记。这部分在下面被注释掉了,但无论是否有这个,我需要登录这个词出现,它的控制器来控制它吗?
当加载时指针标记在页面上时,我可以在网上找到很多相似的例子,并且可以使这些例子正常工作,所以这就是认为它与$ compile方法有关 - 什么我错过了吗?
HTML:
<div ng-app="application" ng-controller="myController"></div>
JS:
var myApp = angular.module('application', []);
myApp.controller('myController', ['$scope', function($scope) {
function showLoginDirective () {
$scope.login = angular.element(document.createElement('login'));
angular.element(document.body).append($scope.login);
};
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?');
}
};
});
上面的代码也在这里:http://jsfiddle.net/d5n6L/7/
答案 0 :(得分:8)
您不应该使用Angular动态地向页面添加元素。很多人,包括我自己,都来自jQuery背景,他们假设我们可以继续这种做法,只需在我们需要的时候添加内容。
然而,对于Angular,逻辑应该在标记中完全可见。那是什么意思?在您的情况下,无论如何都应该有指令,然后使用ng-show
或ng-hide
或ng-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?');
}
};
});
答案 1 :(得分:4)
我建议您使用ng-if以声明方式表示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?');
}
};
});
答案 2 :(得分:3)
我想从控制器向我的页面添加一个指令。
您应该能够在$ scope上定义一个布尔变量,用于确定是否显示登录名。
$scope.loginShouldBeShowing = false;
$scope.showLogin = function() {
$scope.loginShouldBeShowing = true;
};
然后,您可以在模板中使用ngIf指令,仅在此变量设置为true时显示登录模板
<login ng-if="loginShouldBeShowing"></login>
您可以在
修改过的JSFiddle中看到这一点我还添加了一个按钮,以便您可以在控制台中看到link
功能仅在您按下按钮后运行,并且loginShouldBeShowing
设置为true
当加载时指针标记在页面上时,我可以在网上找到很多相似的例子,并且可以使这些例子正常工作,所以这就是认为它与$ compile方法有关
根据我的理解和以前的使用,通常在模板中包含仅在某些情况下使用的指令,即当某些$ scope变量设置为某些值时,使用ngIf,或者ngSwitch或ngShow。我认为如果你试图$编译模板的任何一部分可能会或可能不会使用的每一部分,事情很快就会变得非常混乱。虽然我只是AngularJS的初学者,到目前为止,我只需要在评估自定义指令的属性时使用$ compile,所以
<login after-login="doThisFunction()"></login>
然后可能需要使用$ compile在适当的时候调用doThisFunction()
。
作为一个小侧边栏,变量的名称有点说明在控制器中,您关注模板中发生的事情。在控制器中保留某种模型/业务“状态”更为常见,然后在模板中显示相应的内容。所以你可能在控制器中:
$scope.loginState = 'loggedOut';
然后在模板中:
<login ng-if="loginState == 'loggedOut'"></login>
编辑:我还注意到登录指令与应用程序的其余部分位于不同的模块中。我怀疑这会引起问题,所以我在JSFiddle中修改了这个方面,所以只有一个模块。
编辑:我觉得上面的$ compile和$ parse之间很困惑,所以我会查看有关我使用$ compile的文档/其他来源。