如何访问超过 2 DOM 个元素 "The AngularJS way"?
How to access more than 2 DOM elements "The AngularJS way"?
我开始更好地学习 angularJS,并且我注意到 AngularJS 试图强调将视图与控制器和封装分开。这方面的一个例子是人们告诉我 DOM 操作应该放在指令中。我现在有点掌握了窍门,使用 link 注入当前元素的函数如何实现出色的行为功能,但这并不能解释我经常遇到的问题。
示例:
我有一个侧边栏,我想通过单击一个按钮打开它。如果不使用硬编码的 javascript/jquery 选择器来抓取侧边栏,则无法在按钮的指令 link 函数中执行此操作,我在 angularJS 中看到了非常不受欢迎的东西(hard-编码 dom 选择器)因为它打破了关注点分离。我想解决这个问题的一种方法是让每个我希望操作的元素都有一个属性指令,并在它的 link 函数上,将它的元素 属性 的引用保存到 dom 工厂中,这样每当指令需要访问自身以外的元素时,它可以调用 dom-factory which returns 元素,即使它不知道它来自哪里。但这是 "Angular way" 吗?
我这样说是因为在我当前的项目中我使用的是硬编码选择器,这已经很难维护了,因为我一直在改变我的 css。必须有更好的方法来访问多个 DOM 元素。有什么想法吗?
好吧,如果你在按钮上有一个指令,而你需要的元素在指令之外,你可以将需要切换的元素的 class 作为属性传递
<button my-directive data-toggle-class="sidebar">open</button>
然后在你的指令中
App.directive('myDirective', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
angular.element('.' + attrs.toggleClass).toggleClass('active');
}
};
}
不幸的是,您不会总是让 link 元素参数与您需要操作的内容相匹配。虽然有很多 "angular ways" 可以解决这个问题。
你甚至可以这样做:
<div ng-init="isOpen = false" class="sidebar" ng-class="{'active': isOpen}" ng-click="isOpen = !isOpen">
...
</div>
指令之间最好的沟通方式是通过事件。它还与关注点分离保持一致。您的按钮可以 $broadcast
放在 $rootScope
上,以便所有示波器都能听到。您会发出 sidebar.open
之类的事件。然后侧边栏指令将侦听该事件并对其采取行动。
有多种方法可以解决这个问题。
一种方法是创建一个 sidebar
指令来响应 "well-defined" 广播到 open/close 边栏的消息。
.directive("sidebar", function(){
return {
templateUrl: "sidebar.template.html",
link: function(scope, element){
scope.$root.$on("openSidebar", function(){
// whatever you do to actually show the sidebar DOM content
// e.x. element.show();
});
}
}
});
然后,按钮可以调用某些控制器中的函数来打开侧边栏:
$scope.openSidebar = function(){
$scope.$root.$emit("openSidebar");
}
另一种方法是使用 $sidebar
服务 - 这有点类似于 $modal
在 angularui-bootstrap 中的工作方式,但可以更简化。
我开始更好地学习 angularJS,并且我注意到 AngularJS 试图强调将视图与控制器和封装分开。这方面的一个例子是人们告诉我 DOM 操作应该放在指令中。我现在有点掌握了窍门,使用 link 注入当前元素的函数如何实现出色的行为功能,但这并不能解释我经常遇到的问题。
示例: 我有一个侧边栏,我想通过单击一个按钮打开它。如果不使用硬编码的 javascript/jquery 选择器来抓取侧边栏,则无法在按钮的指令 link 函数中执行此操作,我在 angularJS 中看到了非常不受欢迎的东西(hard-编码 dom 选择器)因为它打破了关注点分离。我想解决这个问题的一种方法是让每个我希望操作的元素都有一个属性指令,并在它的 link 函数上,将它的元素 属性 的引用保存到 dom 工厂中,这样每当指令需要访问自身以外的元素时,它可以调用 dom-factory which returns 元素,即使它不知道它来自哪里。但这是 "Angular way" 吗?
我这样说是因为在我当前的项目中我使用的是硬编码选择器,这已经很难维护了,因为我一直在改变我的 css。必须有更好的方法来访问多个 DOM 元素。有什么想法吗?
好吧,如果你在按钮上有一个指令,而你需要的元素在指令之外,你可以将需要切换的元素的 class 作为属性传递
<button my-directive data-toggle-class="sidebar">open</button>
然后在你的指令中
App.directive('myDirective', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
angular.element('.' + attrs.toggleClass).toggleClass('active');
}
};
}
不幸的是,您不会总是让 link 元素参数与您需要操作的内容相匹配。虽然有很多 "angular ways" 可以解决这个问题。
你甚至可以这样做:
<div ng-init="isOpen = false" class="sidebar" ng-class="{'active': isOpen}" ng-click="isOpen = !isOpen">
...
</div>
指令之间最好的沟通方式是通过事件。它还与关注点分离保持一致。您的按钮可以 $broadcast
放在 $rootScope
上,以便所有示波器都能听到。您会发出 sidebar.open
之类的事件。然后侧边栏指令将侦听该事件并对其采取行动。
有多种方法可以解决这个问题。
一种方法是创建一个 sidebar
指令来响应 "well-defined" 广播到 open/close 边栏的消息。
.directive("sidebar", function(){
return {
templateUrl: "sidebar.template.html",
link: function(scope, element){
scope.$root.$on("openSidebar", function(){
// whatever you do to actually show the sidebar DOM content
// e.x. element.show();
});
}
}
});
然后,按钮可以调用某些控制器中的函数来打开侧边栏:
$scope.openSidebar = function(){
$scope.$root.$emit("openSidebar");
}
另一种方法是使用 $sidebar
服务 - 这有点类似于 $modal
在 angularui-bootstrap 中的工作方式,但可以更简化。