Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/453.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从控制器触发指令的更好方法_Javascript_Angularjs_Angularjs Directive_Triggers_Controller - Fatal编程技术网

Javascript 从控制器触发指令的更好方法

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) {

我有一个指令,它需要根据控制器中服务调用的结果执行一些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>
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的示例。

我想提两件事

  • AngularJs与DOM操作无关

  • 指令的工作概念,它必须完全独立于控制器和所有,必须在所有地方工作

  • 在我看来,指令触发必须基于数据


    因此,如果根据数据触发多个指令,则在单个视图中使用多个指令不会有问题。我看到您正在使用随指令一起传入的文本更新一些
    结果
    元素。该触发器的文本是静态的吗?请忽略指令中的逻辑。这仅仅是为了表明当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);
                    }
    
                });
            }
        };
    });