如何区分同一$范围内的多个指令?

时间:2014-09-03 13:15:23

标签: javascript angularjs angularjs-directive scope

我实际上是从这样的控制器调用指令函数:

function myControllerFunction = function () {
    $scope.highlight();
}

highlight(),是指令中的一个功能。

如果我有两个不同的指令,每个指令都有自己的highlight()功能,该怎么办?

有没有办法获得实际指令 object ,而不是直接通过$ scope访问指令函数?

我更希望明确我想要使用的指令,如下所示:

function myControllerFunction = function () {
    $scope.myDirective.highlight();
}

这可能吗?

如果您对我希望控制器与指令通信的原因感到好奇,这里有一个例子:

我的控制器从用户接收验证引脚并将其提交给服务。如果引脚有效,则服务返回true,否则返回false。

在我的控制器函数中,我检查布尔返回值。如果是真的,我调用一个名为highlight的指令函数,如果它为真,它只会突出显示绿色的div,否则,我称之为红色突出显示。

这是我的控制器功能:

$scope.keypadEnter = function () {
    userService.isCodeValid($scope.code).then(function (result)
    {
        if (JSON.parse(result.data)) {
            $scope.highlight("lime").then(function () {
                $scope.code = "";
                $location.path('/clockin');
            });
        }
        else
        {
            $scope.highlight("red").then(function () {
                $scope.resetDisplay();
                $scope.code = "";
            });
        }
    });
};

这是我的指示突出显示功能:

...
link: function ($scope, $element, $attrs) {
    $scope.highlight = function (color) {
        var deferred = $q.defer();

        $element.effect("highlight", { color: color }, 500);

        $element.find("span").css('color', '#000')
            .animate({ opacity: 0 }, 500, function () {
                $element.find("span").css('opacity', 1).css('color', '#fff')
            });

        $timeout(deferred.resolve, 500);

        return deferred.promise;
    }
...

根据您的建议,我更改了我的指令代码以观察$scope.color变量,如下所示:

angular.module('clockin').directive('grDisplay', function ($q, $timeout) {
    return {
        restrict: 'A',
        link: function ($scope, $element, $attrs) {

            $attrs.observe('color', function (color) {
                var deferred = $q.defer();

                $element.effect("highlight", { color: color }, 500);

                $element.find("span").css('color', '#000')
                    .animate({ opacity: 0 }, 500, function () {
                        $element.find("span").css('opacity', 1).css('color', '#fff')
                    });

                $timeout(deferred.resolve, 500);

                return deferred.promise;
            });
        }
    }
});

这是我的观看代码:

<div data-gr-display ng-attr-color="{{ color }}" class="display"><span>{{code}}</span></div>

但是我收到了这个错误:

TypeError: object doesn't support this property or method « observe »
   at link (http://localhost:18000/App/clockin/keypad/display-directive.js:6:13)
   at nodeLinkFn (http://localhost:18000/Scripts/angular.js:6692:13)
...

2 个答案:

答案 0 :(得分:0)

您的控制器必须从指令调用方法,这似乎很奇怪。你能提供更多关于你为什么这样做的信息吗?

似乎您希望允许您的控制器和指令一起讨论。为此,这里有几个选项。

如果它基于浏览器事件,您可以使用docCreating a Directive that Adds Event Listeners部分中描述的事件监听器

您可以使用angular events来广播活动。

最后,您可能希望在指令模板上调整一个参数,说明它是高亮显示。

根据问题编辑进行编辑:

如果您只需要更改CSS,则可以在指令中使用ng-class属性,如下所示:

<my-directive ng-class="{{ status }}"></my-directive>

使用attribut,您可以执行以下操作:

link: function ($scope, $element, $attrs) {
    $attrs.$observe('color', function(color)){
        var deferred = $q.defer();

        $element.effect("highlight", { color: color }, 500);

        $element.find("span").css('color', '#000')
            .animate({ opacity: 0 }, 500, function () {
                $element.find("span").css('opacity', 1).css('color', '#fff')
            });

        $timeout(deferred.resolve, 500);

        return deferred.promise;
}

在你看来:

<my-directive ng-attr-color="{{ color }}"></my-directive>

或者,如果您需要通知系统,可以参考Angular UI Bootstrap alert (但我仍然不明白为什么你需要几个指令来解决你的问题)

答案 1 :(得分:0)

通常,您与指令进行通信的方式是通过属性,您通常不会在指令级别定义控制器范围中的方法。

我认为你的案例中的正确方法是使用指令中的属性绑定到范围属性,并且您的指令会监视该属性,因此当它更改时,它会运行特定的函数。

可能的实施可能是:

控制器:

$scope.onHightlight = function() {
   if ($scope.highlightColor === 'lime') {
       scope.code = "";
       $location.path('/clockin');
   } else {
       $scope.resetDisplay();
       $scope.code = "";
   }
});
$scope.keypadEnter = function () {
    userService.isCodeValid($scope.code).then(function (result) {
        if (JSON.parse(result.data)) {
            $scope.highlightColor = "lime";
        }
        else {
            $scope.highlightColor = "red";
        }
    });
};

指令:

link: function ($scope, $element, $attrs) {
    var onHightlight = $scope.$eval($attrs['onHightlight']);

    $scope.$watch($attrs['hightlight'], function(color) {

        $element.effect("highlight", { color: color }, 500);

        $element.find("span").css('color', '#000')
            .animate({ opacity: 0 }, 500, function () {
                $element.find("span").css('opacity', 1).css('color', '#fff')
            });

        $timeout(onHightlight, 500);
    }
 ....
}

HTML:

<your-directive highlight="highlightColor" onHighlight="onHightlight"></your-directive>