我有一个指令需要根据控制器中的服务调用结果进行一些DOM操作。以下是我目前正在遵循的方法:
1)在每个控制器范围内创建一个触发器对象,对应于视图中的每个指令 - 在需要时进行dom操作
2)创建指令并根据控制器设置的值进行dom操作;
app.directive("myDirective", function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
attrs.$observe('myDirective', function (value) {
if (value === "true") {
$(element).text("Scrolled to####" + $(element).data("scroll"));
}
});
}
};
});
3)从相应的控制器方法将值设置为true
以触发指令功能
app.controller("controller1", ["$scope", function ($scope) {
$scope.trigger1 = false;
$scope.triggerDirective1 = function () {
$scope.trigger1 = true;
};
$scope.trigger2 = false;
$scope.triggerDirective2 = function () {
$scope.trigger2 = true;
};
}]);
<div id="c1" ng-controller="controller1">Controller 1
<br>List 1
<div my-directive="{{trigger1}}" data-scroll="20"></div>List 2
<div my-directive="{{trigger2}}" data-scroll="30"></div>
<button ng-click="triggerDirective1()">Trigger Directive 1</button>
<button ng-click="triggerDirective2()">Trigger Directive 2</button>
</div>
完整代码在此处 - http://jsfiddle.net/qec35dq4/
我发现这种方法不太好,原因如下:
1)附带指令的视图中会有多个元素
2)每个指令触发器都是独立的。任何时候只有一个指令可以运行。根据视图中的指令数量,我必须跟踪相应控制器中的所有触发器。
有没有更好的方法来解决这个问题,以便可以避免在控制器中跟踪这个触发器范围对象的依赖性?我想到了使用$broadcast/$emit,$on
。但不要认为这也是一个很好的解决方案。请让我知道你的想法。
提前感谢您提供任何帮助
编辑:
新小提琴 - http://jsfiddle.net/86pk8LtL/
稍微改变了一下示例,以反映更多我想要实现的内容 - 页面上将有多个列表将应用此指令。基于后端的一些逻辑,需要选择一些项目列表。选择项目后,应滚动列表,以便第一个选定的项目在视图中(在示例中,我使用数据属性对滚动位置进行硬编码。但实际上指令会进行计算)。此指令的目的只是处理&#34;滚动查看&#34;部分这就是为什么我在保持范围属性方面有点怀疑。请注意,目前的方法工作正常。只是想看看是否有更好的方法。
答案 0 :(得分:1)
AngularJS并不像使用事件驱动的库那样使用DOM查询。 我建议使用控制器提取。 由于Angular支持OOP标准,尝试嵌套控制器,子控制器的范围是从父控制器继承的,这意味着您可以观察触发哪个元素的状态。看看这个基本示例http://jsfiddle.net/qec35dq4/3/ 另外,我建议不要观察属性来将模型传递到指令的范围。这将帮助您避免观察属性更改。
最少但不是最后,你真的不需要注意元素的属性变化。它可以通过您的指令attrs
获得:
app.directive("myDirective", function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
attrs.$observe('myDirective', function (value) {
if (value === "true") {
$("#result").text(attrs.msg);
}
});
}
};
});
修改强> 这是基于您最新的JSFiddle的demo。
答案 1 :(得分:0)
上周我不得不这样做。假设你不想写多个指令,交叉元素指令dom操作可能会很棘手,但是当我这样做时,我查找了ID所需的元素。这将使您不必在范围上定义方法。
<div id="trigger1"></div>List 2
<div id="trigger2"></div>
<button my-directive="trigger1" data-scroll="20">Trigger Directive 1</button>
<button my-directive="trigger2" data-scroll="30">Trigger Directive 2</button>
指令。
app.directive("myDirective", function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var idElem = document.getElementById(attrs.myDirective);
var elementToChange = angular.element(idElem);
element.on("click", function(){
elementToChange.text("Scrolled to####" + attrs.dataScroll);
});
});
}
};
});
答案 2 :(得分:0)
看一下这个指令:https://github.com/iameugenejo/ngScrollTo 这似乎是一种非常巧妙的方式来实现你想要的。
答案 3 :(得分:0)
我想提两件事
AngularJs与DOM操作无关。
指令的工作概念,它必须完全独立于控制器而且必须在所有地方工作。
在我看来,指令触发必须基于数据。
因此,如果根据数据触发多指令,那么在单个视图中使用多指令会出现问题