1

I'm implementing a solution for focusing an element, proposed here. It works fine for a html input, but does not work for a custom directive. Here is the plunk to demonstrate the issue. Clicking "Focus input" upon page load focuses text input next to the button, but clicking "Focus control" doesn't focus text input next to it. Actually, the reason for this is that the $watch function is not called when clicking "Focus control" button (can be seen in browser console).

The question is why that $watch function is not called?

JavaScript

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  $scope.inputFocused = false;
  $scope.controlFocused = false;
});

app.directive('focusedWhen', function () {
  return {
    restrict: 'A',
    link: function (scope, element, attrs) {
      scope.$watch(attrs.focusedWhen, function (value) {
        console.log('focusedWhen', value);
        if (value) {
          element.find('input[type=text]').andSelf().trigger('focus');
        }
      });
    }
  };
});
app.directive('myControl', function () {
  return {
    restrict: 'E',
    scope: {},
    template: '<span><input type="text"></span>',
    link: function (scope, element, attrs) {

    }
  };
});

HTML

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="jquery@*" data-semver="1.7.2" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
    <script data-require="angular.js@1.0.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js" data-semver="1.0.7"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>
    <div>
      <button ng-click="inputFocused = true;">Focus input</button>
      <input type="text" focused-when="inputFocused" />
    </div>
    <div>
      <button ng-click="controlFocused = true;">Focus control</button>
      <my-control focused-when="controlFocused"></my-control>
    </div>
  </body>

</html>
4

1 回答 1

1

看起来问题是您的 $watch 没有触发,因为在后续点击中该值仍然为真。您遇到的问题是您的注意力只能集中在一个输入上。因此,所有按钮/输入对都需要知道如何在它们的对等点之一被单击聚焦时将自己“重置”为 false。相反,我会相反 - 设置获得焦点的指令的真实值,而不是触发焦点的真实值。您可以创建一种新的指令来侦听点击(例如 ng-click 的工作原理),然后遍历指令的子项以查找输入以触发其焦点。同样的指令可以有一个“模糊”事件,link()以知道将其布尔值设置为 false(即controlFocusinputFocus)。

编辑您的指令 myControl 在您为其分配范围时创建了一个隔离范围:{}。从此:_

“隔离”作用域与普通作用域的不同之处在于它在原型上并不从父作用域继承。这在创建可重用组件时很有用,这些组件不应意外读取或修改父范围内的数据。

因此,当您将 {} 分配给范围时,controlFocus 不存在。

于 2013-07-30T17:36:33.020 回答