所以我已经和AngularJS合作了相当长的时间,但仍然需要了解指令背后的场景。
我正在尝试构建一个指令,它根据需要附加一个模态窗口,如果不再需要则将其从DOM中分离出来。
所以我这样做了:
app.directive('myDirective',function($document){
return{
restrict: 'E',
templateUrl: 'partials/modules/template.html',
link: function($scope,$element){
var body = $document.find('body').eq(0);
$element.remove();
$scope.create = function(){
body.append($element);
};
}
}
});
发现它会导致视图和控制器之间的链接丢失。
到目前为止,非常糟糕。
但我在这里缺少什么基本概念?什么是实现这个目标的正确方法?
我脑子里有一些杂乱的(和hacky)选项,包括
ng-show
hide
的CSS类它们看起来很奇怪而且对我来说完全错了,我特别不想使用样式属性来做这件事。
我也不想使用Angular-UI的模态模块。
答案 0 :(得分:2)
问题是当你在create方法中调用$ element.remove()然后调用body.append($ element)时,它不再是“已编译”的角度。这就是链接被破坏的原因。每次想要展示时编译和追加都不是最有效的解决方案(如上所述)。
为什么使用CSS显示和隐藏元素/模态会被视为hacky?这就是我在大多数UI框架中看到它的方式。
我已经把我认为你的problem is(模板中的按钮不能调用hideMe函数)和使用CSS class的示例放在一起。
忽略样式的简单性:
.modal.show {
display: block;
}
.modal {
display: none;
position: absolute;
height: 100px;
width: 100px;
margin: 15px auto auto;
border: 1px solid blue;
padding: 5px;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: white;
z-index: 200;
}
在范围方法中使用addClass和removeClass来创建/隐藏模态:
mod.directive("myDirective", function () {
return{
restrict: 'E',
replace: true,
template: '<div class="modal">Hello<button ng-click="hideMe()">×</button></div>',
link: function($scope,$element){
var shade = angular.element('<div class="shade"></div>');
$scope.create = function(){
$element.addClass("show");
$element.after(shade);
};
$scope.hideMe = function () {
$element.removeClass("show");
shade.remove();
}
}
}
});
隐藏/显示元素是CSS非常好的事情之一。如果你想用最少的额外工作来使用CSS,你也可以获得一些不错的动画和过渡。
答案 1 :(得分:2)
您绝对应该重新考虑使用样式属性的观点。这是有角度的推荐方式:
&#39; AngularJS的主要设计目标之一是允许应用程序开发人员在很少或没有直接操作DOM的情况下构建Web应用程序。在许多情况下,这也会导致更具声明性的编程风格。这使得业务逻辑可以轻松进行单元测试,并大大提高了开发应用程序的速度。&#39; What is the AngularJS way to show or hide a form element?
我一直都是这样做的。使用ng-class和json,在我看来,这是最简单的方法,也是最简单的测试方法。这是一个粗略的想法。此外,您不需要将元素附加到正文,这是链接阶段的整个目的:
app.directive('myDirective',function($document){
return{
restrict: 'E',
templateUrl: '<div myDirective ng-class="{\'hideClass\':object.hide===true, \'showClass\':object.show===true "></div>',
link: function($scope,$element){
scope.element= {hide:false, show:true}
if(someCondition) {
scope.element.hide = true;
}
if (anotherCondition) {
scope.element.show = true;
}
}
}
});
然后,在你的测试中:
it('should be hidden if...', function () {
angular.mock.inject(function ($compile, $rootScope) {
var scope = $rootScope.$new();
var elem = $compile('<div myDirective></div>')(scope);
// ... some conditional code to manipulate scope.element json, you may need timeout to wait for DOM to load so you can check that the class is present
expect(elem.hasClass('hideClass')).toBe(true);
});
});