重写指令不使用隔离范围?

时间:2014-10-30 16:39:18

标签: javascript angularjs angularjs-directive

我想要将两个简单的指令应用于元素。

当条件变为true时,该指令将焦点放在特定元素上:

.directive('focusOnCondition', function ($timeout) {
    return {
        restrict: 'A',
        scope: {
            condition: '=focusOnCondition',
        },
        link: function (scope, el, attr) {
            scope.$watch('condition', function (value) {
                if (value) {
                    $timeout(function () {
                        el[0].focus();
                    });
                }
            });
        }
    };
});

当用户按下'enter'时,该指令调用一个函数:

.directive('triggerOnEnter', function () {
    return {
        restrict: "A",
        scope: {
            func: '&triggerOnEnter'
        },
        link: function (scope, el, attr) {
            $(el).keypress(function (event) {
                if (event.which == 13) scope.func();
            });
        }
    };
})

这两个指令分开工作,但如果我尝试将它们应用于同一个元素,它们就不起作用。例如:

<form ng-show="pastingResults">

    <textarea placeholder="Paste results and press 'enter'"
              ng-model="pastedResultData"
              trigger-on-enter="pasteResults()"
              focus-on-condition="pastingResults"></textarea>

    <button type="submit" ng-click="pasteResults()">Submit</button>
</form>

导致错误[$compile:multidir] Multiple directives (...) on (...)

我该如何解决这个问题?我是Angular JS的新手,并且“把它置于一个孤立的范围内”是我在制作指令时唯一知道如何做的事情。我认为必须能够在不使用隔离范围的情况下实现这些,但我不知道如何。

有人能举个例子吗?

1 个答案:

答案 0 :(得分:1)

如果删除隔离的作用域,则可以通过使用传递给链接函数的attrs对象直接查看元素的属性来访问这些选项,并在需要时使用$eval进行评估:

app.directive('focusOnCondition', function ($timeout) {
  return {
    restrict: 'A',
    link: function (scope, el, attr) {
      scope.$watch(attr.focusOnCondition, function (value) {
        if (value) {
          $timeout(function () {
            el[0].focus();
          });
        }
      });
    }
  };
});

app.directive('triggerOnEnter', function () {
  return {
    restrict: "A",
    link: function (scope, el, attr) {
      $(el).keypress(function (event) {
        if (event.which == 13) {
          scope.$eval(attr.triggerOnEnter);
        }
      });
    }
  };
});

可以看到这些工作在http://plnkr.co/edit/1iOBNVlmRxm8HGRrObBd?p=preview