如何将$ scope中的变量传递给指令,并反转?

Yan*_*ong 4 html javascript jquery angularjs angular-directive

我目前正在尝试实现一个应该使一些DOM元素闪烁的指令.为此,我$timeout用于将元素的可见性设置为可见或隐藏.我的问题是,如果在$timeout通话中我硬编码一个值(比如'500'),一切都运行得很顺利.但是如果我尝试通过变量传递这个参数,我会让元素快速闪烁,好像没有输入任何参数(默认值为'0').

HTML

<button class="btn btn-key"><span class="blink" blinkSpeed='500'>Q</span></button>
{{displayBlinkSpeed}}
Run Code Online (Sandbox Code Playgroud)

JS

.directive('blink',function($timeout){
return{
    restrict:'ACE',
    transclude: true,
    scope:{
        blinkSpeed: '='
    },
    link: function(scope,element,attrs){
        function showElement(){             
            var speed = parseInt(scope.blinkSpeed);
            element.css("visibility","visible");
            $timeout(hideElement,speed);
            scope.displayBlinkSpeed = speed;
        }

        function hideElement(){
            var speed = parseInt(scope.blinkSpeed);
            element.css("visibility","hidden");
            $timeout(showElement,speed);
            scope.displayBlinkSpeed = speed;
        }

        showElement();
    },
    template: '<span ng-transclude></span>',
    replace: true
    };
});
Run Code Online (Sandbox Code Playgroud)

另外,我忘了提到{{displayBlinkSpeed}}HTML中也没有显示任何内容.我的猜测是我的指令无法与DOM通信(接收/发送)信息.不幸的是,我还没有办法让它发挥作用.我错过了/误解了什么吗?

New*_*Dev 5

首先,{{displayBlinkSpeed}}不会显示任何内容,因为displayBlinkSpeed它只在指令的隔离范围内定义 - 它undefined在它之外.

至于blinkSpeed- 当你绑定到一个属性时,Angular会对属性名称进行规范化,因此scope: {blinkSpeed: "="}绑定到blink-speed="500"属性(不是blinkSpeed="500"属性).没有它,$scope.blinkSpeed === undefinedparseInt(undefined) === NaN,会导致闪烁.

将HTML更改为:

<span class="blink" blink-speed='500'>Q</span>
Run Code Online (Sandbox Code Playgroud)

有些偏离主题:

1:您不需要这样做,parseInt(scope.blinkSpeed)因为它"="会正确地解析为整数.所以,以下内容也可以正常工作:

$timeout(hideElement, $scope.blinkSpeed);
Run Code Online (Sandbox Code Playgroud)

2:既然你不打算修改指令中的闪烁速度,那么"="使用双向绑定是浪费的- 而是使用单向绑定到表达式"&":

scope: {
  blinkSpeed: "&",
},
link: function(scope){
  var speed = scope.blinkSpeed();
  $timeout(hideElement, speed);
}
Run Code Online (Sandbox Code Playgroud)