2013-02-08 33 views
9
trường hợp

Test: http://jsbin.com/ahugeg/4/edit (Hơi dài)Thay đổi tập trung vào đầu vào trên một sự kiện quan trọng trong AngularJS

Trong trường hợp thử nghiệm trên, tôi có ba yếu tố đầu vào, tạo ra bởi ng-repeat chỉ thị. Ý định của tôi trong trường hợp thử nghiệm này là việc nhấn các mũi tên lên/xuống ở một trong các đầu vào này sẽ chuyển tiêu điểm đến đầu vào theo hướng tương ứng, nếu có đầu vào có sẵn theo hướng đó.

Tôi mới tham gia AngularJS, vì vậy tôi có thể đang bỏ lỡ một số cách đơn giản để thực hiện việc này. Dù sao, tôi đã xác định hai chỉ thị mới (on-upon-down), để xử lý các sự kiện lên và xuống và đang gọi các phương thức $scope.focusNext$scope.focusPrev, chuyển mục nhập chính xác, tương ứng với tiêu điểm cần di chuyển. Đây là nơi tôi bị mắc kẹt.

Tôi biết nó không phải là góc chiều để đối phó với các yếu tố DOM trong bộ điều khiển, nhưng tôi không thể nhìn thấy như thế nào tập trung có thể được xem như là một thuộc tính/tài sản của một người mẫu. Tôi thậm chí còn nghĩ đến việc có một số riêng biệt $scope.focusedEntry, nhưng sau đó tôi có nên xem để thay đổi về thuộc tính đó không? Ngay cả khi tôi làm và tôi phát hiện các thay đổi, làm thế nào tôi có thể truy cập vào phần tử đầu vào tương ứng với mục nhập mà tôi muốn tập trung?

Bất kỳ trợ giúp nào về cách thực hiện việc này được đánh giá rất nhiều.

Trả lời

15

tôi chỉ viết này lên và thử nghiệm nó một thời gian ngắn - nó làm những gì bạn muốn mà không tất cả sự lộn xộn thêm trong bộ điều khiển của bạn và trong HTML. Xem nó hoạt động here.

HTML:

<body ng-controller="Ctrl"> 
    <input ng-repeat="entry in entries" value="{{entry}}" key-focus /> 
</body> 

Bộ điều khiển:

function Ctrl($scope) { 
    $scope.entries = [ 'apple', 'ball', 'cow' ]; 
} 

Chỉ thị:

app.directive('keyFocus', function() { 
    return { 
    restrict: 'A', 
    link: function(scope, elem, attrs) { 
     elem.bind('keyup', function (e) { 
     // up arrow 
     if (e.keyCode == 38) { 
      if(!scope.$first) { 
      elem[0].previousElementSibling.focus(); 
      } 
     } 
     // down arrow 
     else if (e.keyCode == 40) { 
      if(!scope.$last) { 
      elem[0].nextElementSibling.focus(); 
      } 
     } 
     }); 
    } 
    }; 
}); 
+0

Cảm ơn bạn.Giải pháp của bạn đã cho tôi ý tưởng và động lực để làm việc một mình. Tôi đã có một cách tiếp cận hơi khác, xác định một chỉ thị trên phần tử cha của 'ng-repeat'ed, nó lấy bộ chọn của' input' mà tiêu điểm sẽ được di chuyển. Tôi sẽ đăng giải pháp của tôi sau một phút. Cảm ơn một lần nữa. –

6

Tôi gặp sự cố tương tự và sử dụng chỉ thị đơn giản này. Nó hoạt động như ng-show và ng-hide would- chỉ chú trọng, nếu nó thuộc tính giải quyết là đúng:

.directive('focusOn',function() { 
    return { 
     restrict : 'A', 
     link : function($scope,$element,$attr) { 
      $scope.$watch($attr.focusOn,function(focusVal) { 
       if(focusVal === true) { 
        setTimeout(function() { 
         $element.focus(); 
        },50); 
       } 
      }); 
     } 
    } 
}) 
+0

Hah! Giải pháp tốt đẹp và đơn giản. Cảm ơn bạn rất nhiều. –

+0

Giải pháp tuyệt vời. Bạn cần phải kiểm tra focusVal triệt để hơn. ng-show và ng-hide sử dụng toBoolean (giá trị) mà không may là một chức năng góc riêng tư. Tôi đã chuyển dịch vụ này sang dịch vụ và gọi Boolean.toBoolean (focusVal) === true. – shapeshifter

4

Lấy cảm hứng từ @ giải pháp Trevor, đây là những gì tôi giải quyết trên,

app.directive('focusIter', function() { 

    return function (scope, elem, attrs) { 
     var atomSelector = attrs.focusIter; 

     elem.on('keyup', atomSelector, function (e) { 
      var atoms = elem.find(atomSelector), 
       toAtom = null; 

      for (var i = atoms.length - 1; i >= 0; i--) { 
       if (atoms[i] === e.target) { 
        if (e.keyCode === 38) { 
         toAtom = atoms[i - 1]; 
        } else if (e.keyCode === 40) { 
         toAtom = atoms[i + 1]; 
        } 
        break; 
       } 
      } 

      if (toAtom) toAtom.focus(); 

     }); 

     elem.on('keydown', atomSelector, function (e) { 
      if (e.keyCode === 38 || e.keyCode === 40) 
       e.preventDefault(); 
     }); 

    }; 
}); 

Điều này xác định thuộc tính focus-iter để được đặt trên phần tử gốc của tất cả các yếu tố đầu vào lặp lại. Xem hoạt động này tại đây: http://jsbin.com/ahugeg/10/.

Lợi thế hơn @ Trevor là tôi có thể đặt bộ chọn tùy ý cho giá trị của thuộc tính focus-iter để chỉ định chính xác yếu tố nào mà tính năng tập trung nhảy sẽ hoạt động. Ví dụ: hãy thử đặt thuộc tính focus-iter thành input:even :). Điều này giúp từ trong ứng dụng của tôi, các input s đi kèm với khá nhiều đánh dấu phụ xung quanh chúng, không giống như trường hợp thử nghiệm.

+0

Đó là thực sự khá gọn gàng những gì bạn đã làm ở đó. Tôi thích cách cơ bản mọi thứ hoạt động như 'focus-iter =" form> * "'. –

+0

Cảm ơn. Hoặc thậm chí 'focus-iter =" [key-focus] "', khi đầu vào có thuộc tính 'key-focus' như đánh dấu trong câu trả lời của bạn :) –

+0

có thể giúp tôi với đầu vào bên trong ô bảng? –

Các vấn đề liên quan