Javascript 从控制器触发指令的更好方法
我有一个指令,它需要根据控制器中服务调用的结果执行一些DOM操作。以下是我目前采用的方法: 1) 在视图中每个指令对应的每个控制器作用域中创建一个触发器对象,以便在需要时进行dom操作 2) 创建指令并根据控制器中设置的值进行dom操作Javascript 从控制器触发指令的更好方法,javascript,angularjs,angularjs-directive,triggers,controller,Javascript,Angularjs,Angularjs Directive,Triggers,Controller,我有一个指令,它需要根据控制器中服务调用的结果执行一些DOM操作。以下是我目前采用的方法: 1) 在视图中每个指令对应的每个控制器作用域中创建一个触发器对象,以便在需要时进行dom操作 2) 创建指令并根据控制器中设置的值进行dom操作 app.directive("myDirective", function () { return { restrict: 'A', link: function (scope, element, attrs) {
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>
app.controller(“controller1”),[“$scope”,函数($scope){
$scope.trigger1=false;
$scope.triggerDirective1=函数(){
$scope.trigger1=true;
};
$scope.trigger2=false;
$scope.triggerDirective2=函数(){
$scope.trigger2=true;
};
}]);
控制器1
清单1
清单2
触发指令1
触发指令2
完整的代码在这里-
我发现这种方法不太好,原因如下:
1) 视图中将有多个元素,并附有指令
2) 每个指令触发器都是独立的。在任何时候只有一个指令在运行。根据视图中的指令数,我必须跟踪各个控制器中的所有触发器
是否有更好的方法来解决此问题,从而避免在控制器中跟踪此触发器作用域对象的依赖性?我考虑使用$broadcast/$emit,$on
。但也不要认为这是一个好的解决方案。请让我知道你的想法
提前谢谢你的帮助
编辑:
新小提琴-
将示例稍作修改,以反映我试图实现的目标-页面上将有多个列表应用此指令。根据后端的一些逻辑,需要在列表中选择一些项目。选择项目后,应滚动列表,以便查看第一个选定的项目(在本例中,我使用数据属性对scrollposition进行硬编码。但实际上,指令将进行计算)。此指令的目的只是处理“滚动到视图”这就是为什么我对保留它的scope属性有些怀疑。请注意,目前的方法运行良好。我只是想看看是否有更好的方法来解决这个问题。上周我不得不做类似的事情。假设您不想编写多个指令,跨元素指令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>
请看一下本指令:
这似乎是一种很好的方法来实现您想要的功能。AngularJS并不像事件驱动库那样真正使用DOM查询。 我建议使用控制器抓取。 由于Angular支持OOP标准尝试嵌套控制器,所以子控制器的作用域继承自父控制器,这意味着您可以观察触发元素的状态。看看这个基本的例子 此外,我建议将模型传递到指令的范围,而不是观察属性。这将帮助您避免观察属性更改 至少但不是最后一个,您实际上不需要关注元素的属性更改。可通过指令的
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);
}
});
}
};
});
编辑
这是一个基于您最新的JSFIDLE的示例。我想提两件事
因此,如果根据数据触发多个指令,则在单个视图中使用多个指令不会有问题。我看到您正在使用随指令一起传入的文本更新一些
结果元素。该触发器的文本是静态的吗?请忽略指令中的逻辑。这仅仅是为了表明当triggeredAs在任何给定的时间只有一个触发器处于活动状态时,指令将执行一些DOM操作,假设不显示具有不同触发器的其他div是否正确?您的示例有点笨拙,如果您提供了一个更真实的代码示例,将更容易为您提供帮助。更新了示例。此外,所有带有触发器的div都将始终显示。。
app.directive("myDirective", function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
attrs.$observe('myDirective', function (value) {
if (value === "true") {
$("#result").text(attrs.msg);
}
});
}
};
});