2012-12-28 119 views
15

單擊複選框時是否有更清晰的方式將焦點委派給元素。這裏的髒版我砍死:AngularJS - 在單擊複選框時聚焦輸入元素

HTML

<div ng-controller="MyCtrl"> 
    <input type="checkbox" ng-change="toggled()"> 
    <input id="name"> 
</div> 

的JavaScript

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

function MyCtrl($scope, $timeout) { 
    $scope.value = "Something"; 
    $scope.toggled = function() { 
     console.debug('toggled'); 
     $timeout(function() { 
      $('#name').focus(); 
     }, 100); 
    } 
} 

的jsfiddle:http://jsfiddle.net/U4jvE/8/

+0

延遲值爲0(而不是100)也應該起作用。 –

回答

17

這個怎麼樣? plunker

$scope.$watch('isChecked', function(newV){ 
     newV && $('#name').focus(); 
    },true); 

@asgoth和@Mark Rajcok是正確的。我們應該使用指令。我只是懶惰。

這是指令版本。 plunker我認爲把它作爲指令的一個很好的理由是你可以重用這個東西。

所以在你的HTML你可以分配不同的情態不同組的

<input type="checkbox" ng-model="isCheckedN"> 
<input xng-focus='isCheckedN'> 


directive('xngFocus', function() { 
    return function(scope, element, attrs) { 
     scope.$watch(attrs.xngFocus, 
     function (newValue) { 
      newValue && element.focus(); 
     },true); 
     };  
}); 
0

一個清潔的方法是使用一個指令來進行切換:

app.directive('toggle', function() { 
    return { 
     restrict: 'A', 
     scope: { 
     selector: '=' 
     }, 
     link: function(scope, element, attrs) { 
      element.on('change', function() { 
       $(scope.selector).focus(); 
       scope.$apply(); 
      }); 
     } 
    }: 
}); 

你的HTML將某物像:

<input type='checkbox' toggle selector='#name'> 
+0

如果選擇器在頁面上不唯一,該怎麼辦?在這種情況下,我會有許多'.name's,但只有其中一個匹配當前範圍。 – kolrie

7

另一個指令實現(不需要jQuery)和借用一些@ maxisam代碼:

myApp.directive('focus', function() { 
    return function(scope, element) { 
     scope.$watch('focusCheckbox', 
     function (newValue) { 
      newValue && element[0].focus() 
     }) 
    }  
}); 

HTML:

<input type="checkbox" ng-model="focusCheckbox"> 
<input ng-model="name" focus> 

Fiddle

由於此指令不會創建隔離範圍(或子範圍),因此該指令假定範圍具有定義的focusCheckbox屬性。

+0

@maxisam,我喜歡你在答案中添加的屬性。順便說一句,沒有element.focus()爲你工作?我不得不使用元素[0] .focus()。 –

+0

我忘了你是包含jQuery,所以這就是爲什麼element.focus()的作品。如果沒有包含jQuery,我們必須使用element [0] .focus()。 –

5

如果你想讓它更有趣,並且支持任意表達式進行評估(不僅是變量),你可以這樣做:

app.directive('autofocusWhen', function ($timeout) { 
    return { 
     link: function(scope, element, attrs) { 
      scope.$watch(attrs.autofocusWhen, function(newValue){ 
       if (newValue) { 
        $timeout(function(){ 
         element.focus(); 
        }); 
       } 
      }); 
     } 
    }; 
}); 

而且你的HTML中可以多一點去耦,像即:

<input type="checkbox" ng-model="product.selected" /> 
{{product.description}} 
<input type="text" autofocus-when="product.selected" /> 
+1

爲什麼使用$ timeout服務? – Alpha

+1

@Alpha,出於某種原因,在AngularJS中,'$ watch'表達式在html重新繪製前發生,因此立即調用'element。焦點();'會聚焦元素,並立即失去焦點,隨着範圍的改變,元素被重繪。使用'$ timeout'服務是一種已知的解決方法,用於在隊列中添加更改,所以它恰好在HTML重繪之後發生。 – ViniciusPires

+1

它像一個魅力工作 –

相關問題