- When a Modal is opened, set focus on a predefined <input> inside this Modal. (打开模态后,将焦点放在此模态内的预定义<input>上。)
Define a directive and have it $watch a property/trigger so it knows when to focus the element: (定义一个指令,并使其$ watch一个属性/触发器,以便它知道何时集中该元素:)
Name: <input type="text" focus-me="shouldBeOpen">
app.directive('focusMe', ['$timeout', '$parse', function ($timeout, $parse) {
return {
//scope: true, // optionally create a child scope
link: function (scope, element, attrs) {
var model = $parse(attrs.focusMe);
scope.$watch(model, function (value) {
console.log('value=', value);
if (value === true) {
$timeout(function () {
element[0].focus();
});
}
});
// to address @blesh's comment, set attribute value to 'false'
// on blur event:
element.bind('blur', function () {
console.log('blur');
scope.$apply(model.assign(scope, false));
});
}
};
}]);
Plunker (柱塞)
The $timeout seems to be needed to give the modal time to render. ($ timeout似乎需要给定模态时间来渲染。)
'2.' ('2。) Everytime <input> becomes visible (eg by clicking some button), set focus on it. (每当<input>变为可见时(例如,通过单击某些按钮),请将焦点设置在它上面。)
Create a directive essentially like the one above. (创建一个基本上与上述指令相似的指令。) Watch some scope property, and when it becomes true (set it in your ng-click handler), execute element[0].focus()
. (观察一些scope属性,当它变为true时(在ng-click处理程序中进行设置),执行element[0].focus()
。) Depending on your use case, you may or may not need a $timeout for this one: (根据您的用例,您可能需要也可能不需要$ timeout:)
<button class="btn" ng-click="showForm=true; focusInput=true">show form and
focus input</button>
<div ng-show="showForm">
<input type="text" ng-model="myInput" focus-me="focusInput"> {{ myInput }}
<button class="btn" ng-click="showForm=false">hide form</button>
</div>
app.directive('focusMe', function($timeout) {
return {
link: function(scope, element, attrs) {
scope.$watch(attrs.focusMe, function(value) {
if(value === true) {
console.log('value=',value);
//$timeout(function() {
element[0].focus();
scope[attrs.focusMe] = false;
//});
}
});
}
};
});
Plunker (柱塞)
Update 7/2013 : I've seen a few people use my original isolate scope directives and then have problems with embedded input fields (ie, an input field in the modal). (更新7/2013 :我已经看到一些人使用我原来的隔离范围指令,然后在嵌入的输入字段(即模态中的输入字段)方面遇到问题。) A directive with no new scope (or possibly a new child scope) should alleviate some of the pain. (没有新作用域(或可能新的子作用域)的指令应减轻某些痛苦。) So above I updated the answer to not use isolate scopes. (因此,以上我更新了不使用隔离范围的答案。) Below is the original answer: (以下是原始答案:)
Original answer for 1., using an isolate scope: (1.使用隔离范围的原始答案:)
Name: <input type="text" focus-me="{{shouldBeOpen}}">
app.directive('focusMe', function($timeout) {
return {
scope: { trigger: '@focusMe' },
link: function(scope, element) {
scope.$watch('trigger', function(value) {
if(value === "true") {
$timeout(function() {
element[0].focus();
});
}
});
}
};
});
Plunker . (柱塞 。)
Original answer for 2., using an isolate scope: (2.使用隔离范围的原始答案:)
<button class="btn" ng-click="showForm=true; focusInput=true">show form and
focus input</button>
<div ng-show="showForm">
<input type="text" focus-me="focusInput">
<button class="btn" ng-click="showForm=false">hide form</button>
</div>
app.directive('focusMe', function($timeout) {
return {
scope: { trigger: '=focusMe' },
link: function(scope, element) {
scope.$watch('trigger', function(value) {
if(value === true) {
//console.log('trigger',value);
//$timeout(function() {
element[0].focus();
scope.trigger = false;
//});
}
});
}
};
});
Plunker . (柱塞 。)
Since we need to reset the trigger/focusInput property in the directive, '=' is used for two-way databinding. (由于我们需要在指令中重置trigger / focusInput属性,因此“ =”用于双向数据绑定。) In the first directive, '@' was sufficient. (在第一个指令中,“ @”就足够了。) Also note that when using '@' we compare the trigger value to "true" since @ always results in a string. (还要注意,当使用“ @”时,我们将触发值与“ true”进行比较,因为@始终会产生字符串。)