角度ng-blur不适用于ng-hide

时间:2014-01-13 16:22:55

标签: angularjs

在文字输入中使用指令focus-me="inTextModeInput"

app.directive('focusMe', function($timeout) {
    /*focuses on input
     <input type="text" focus-me="focusInput">
     */
        return {
            scope: { trigger: '=focusMe' },
            link: function(scope, element) {
                scope.$watch('trigger', function(value) {
                    if(value === true) {
                        $timeout(function() {
                            element[0].focus();
                            scope.trigger = false;
                        });
                    }
                });
            }
        };
    });

实际上有2个输入,都使用focus-me 当我以编程方式将值设置为关注输入时,不会调用其他ng-blur

注意:我也在ng-repeat中使用它。

1 个答案:

答案 0 :(得分:2)

隔离范围

调用模糊,但您没有看到它,因为您已创建具有隔离范围的指令。 ng-blur范围内执行$parent。当指令实现可重用模板时,您应该只使用隔离范围。

触发器双向绑定

'scope.trigger = false'这一行也设置了一个不同的布尔值,因为它位于不同的范围内。如果要为指令中的变量赋值,则应始终将该值包装在另一个对象中:var focus = { me: true }并将其设置为trigger=focus.me

更好的解决方案

但我根本不会将trigger设置为false。 AngularJS是一个基于MVC / MVVM的框架,它具有用户界面的模型状态。此状态应为幂等;意味着如果存储当前状态,则重新加载页面并恢复状态,用户界面应与之前完全相同。

所以你可能需要的是一个指令

  • 没有孤立的范围(允许所有其他指令起作用:ng-blur,ng-focus,...)
  • 跟踪表示焦点状态的布尔值
  • 当元素失去焦点时将此布尔值设置为false

可能更容易看到这件事在行动:working plunker

也许this (other) plunker可以让您更深入地了解范围和指令。

<强>代码

myApp.directive('myFocus', function($parse, $timeout) {

  return {
    restrict: 'A',
    link: function myFocusLink($scope, $element, $attrs, ctrls) {

        var e = $element[0];

        // Grab a parser from the provided expression so we can
        // read and assign a value to it.

        var getModel = $parse($attrs.myFocus);
        var setModel = getModel.assign;

        // Watch the parser -- and focus if true or blur otherwise.

        $scope.$watch(getModel, function(value) {
          if(value) {
            e.focus();
          } else {
            e.blur();
          }
        });

        function onBlur() {
          $timeout(function() {
            setModel($scope, false);  
          });
        }

        function onFocus() {
          $timeout(function() {
            setModel($scope, true);  
          });
        }

        $element.on('focus', onFocus);
        $element.on('blur', onBlur);

        // Cleanup event registration if the scope is destroyed

        $scope.$on('$destroy', function() {
          $element.off('focus', onFocus);
          $element.off('blur', onBlur);
        });
    }
  };
});