तत्व फोकस कोणीय तरीके से सेट करें


113

कोणीय के साथ फोकस तत्वों को कैसे सेट किया जाए, इसके उदाहरणों की तलाश करने के बाद, मैंने देखा कि उनमें से ज्यादातर फ़ोकस सेट करने के लिए देखने के लिए कुछ चर का उपयोग करते हैं, और उनमें से अधिकांश प्रत्येक फ़ील्ड के लिए एक अलग चर का उपयोग करते हैं जिसे वे फ़ोकस सेट करना चाहते हैं। एक रूप में, बहुत सारे क्षेत्रों के साथ, इसका मतलब है कि बहुत सारे विभिन्न चर।

जेक्वेरी तरीके को ध्यान में रखते हुए, लेकिन कोणीय तरीके से ऐसा करने के लिए, मैंने एक समाधान बनाया कि हम किसी भी फ़ंक्शन में तत्व की आईडी का उपयोग करके ध्यान केंद्रित करें, इसलिए, जैसा कि मैं कोणीय में बहुत नया हूं, मैं कुछ राय लेना चाहता हूं यदि यह तरीका सही है, समस्याएँ हैं, जो भी हो, कुछ भी जो मुझे कोणीय में बेहतर तरीके से करने में मदद कर सकता है।

मूल रूप से, मैं एक निर्देश बनाता हूं जो उपयोगकर्ता द्वारा परिभाषित एक गुंजाइश मान को निर्देश के साथ, या डिफ़ॉल्ट का ध्यान केंद्रित करता है, और जब वह मान तत्व के आईडी के समान होता है, तो वह तत्व सेट फोकस होता है।

angular.module('appnamehere')
  .directive('myFocus', function () {
    return {
      restrict: 'A',
      link: function postLink(scope, element, attrs) {
        if (attrs.myFocus == "") {
          attrs.myFocus = "focusElement";
        }
        scope.$watch(attrs.myFocus, function(value) {
          if(value == attrs.id) {
            element[0].focus();
          }
        });
        element.on("blur", function() {
          scope[attrs.myFocus] = "";
          scope.$apply();
        })        
      }
    };
  });

एक इनपुट जिसे किसी कारण से ध्यान केंद्रित करने की आवश्यकता है, वह इस तरह से करेगा

<input my-focus id="input1" type="text" />

ध्यान केंद्रित करने के लिए यहां कोई भी तत्व:

<a href="" ng-click="clickButton()" >Set focus</a>

और उदाहरण फ़ंक्शन जो फोकस सेट करता है:

$scope.clickButton = function() {
    $scope.focusElement = "input1";
}

क्या यह कोणीय में एक अच्छा समाधान है? क्या यह समस्या है कि मेरे खराब अनुभव के साथ मुझे अभी तक नहीं देखा गया है?

जवाबों:


173

आपके समाधान के साथ समस्या यह है कि यह तब अच्छा काम नहीं करता है जब अन्य निर्देशों से बंधा होता है जो एक नया दायरा बनाता है, जैसे ng-repeat। एक बेहतर समाधान बस एक सेवा फ़ंक्शन बनाना होगा जो आपको अपने नियंत्रकों के भीतर अनिवार्य रूप से तत्वों को केंद्रित करने या HTML में घोषित तत्वों पर ध्यान केंद्रित करने में सक्षम बनाता है।

डेमो

JAVASCRIPT

सर्विस

 .factory('focus', function($timeout, $window) {
    return function(id) {
      // timeout makes sure that it is invoked after any other event has been triggered.
      // e.g. click events that need to run before the focus or
      // inputs elements that are in a disabled state but are enabled when those events
      // are triggered.
      $timeout(function() {
        var element = $window.document.getElementById(id);
        if(element)
          element.focus();
      });
    };
  });

आदेश

  .directive('eventFocus', function(focus) {
    return function(scope, elem, attr) {
      elem.on(attr.eventFocus, function() {
        focus(attr.eventFocusId);
      });

      // Removes bound events in the element itself
      // when the scope is destroyed
      scope.$on('$destroy', function() {
        elem.off(attr.eventFocus);
      });
    };
  });

नियंत्रक

.controller('Ctrl', function($scope, focus) {
    $scope.doSomething = function() {
      // do something awesome
      focus('email');
    };
  });

एचटीएमएल

<input type="email" id="email" class="form-control">
<button event-focus="click" event-focus-id="email">Declarative Focus</button>
<button ng-click="doSomething()">Imperative Focus</button>

मुझे वास्तव में यह समाधान पसंद है। क्या आप समझा सकते हैं, हालांकि, $ टाइमआउट का उपयोग करने का कारण थोड़ा अधिक है? क्या आपने "एंगुलर थिंग" या "डोम थिंग" के कारण इसका उपयोग किया है?
user1821052

यह सुनिश्चित करता है कि यह किसी भी पचाने वाले चक्र के बाद चलता है जो कोणीय करता है, लेकिन यह पचाने वाले चक्रों को बाहर करता है जो एक अतुल्यकालिक कार्रवाई के बाद प्रभावित होते हैं जो टाइमआउट के बाद निष्पादित होते हैं।
रायबेलर

3
धन्यवाद! उन लोगों के लिए जहां यह कोणीय डॉक्स में संदर्भित है, यहां लिंक (मुझे खोजने के लिए हमेशा के लिए लिया गया है)
user1821052

@ryeballar, धन्यवाद!। अच्छा सरल उपाय है। हालांकि एक सवाल है। क्या मैं किसी घटना के होने की प्रतीक्षा करने के बजाय विशेषता के माध्यम से बनाई गई फैक्ट्री का उपयोग कर सकता हूं?
प्रतीक गायकवाड़

4
यह एक इनपुट पर ध्यान केंद्रित करने के लिए कोणीय में आवश्यक कार्य की मात्रा को पागल कर रहा है।
ब्रूनो सैंटोस

19

इस समाधान के बारे में, हम सिर्फ एक निर्देश बना सकते हैं और इसे DOM तत्व के साथ संलग्न कर सकते हैं जिसे किसी दिए गए शर्त के संतुष्ट होने पर ध्यान केंद्रित करना होगा। इस दृष्टिकोण का पालन करके हम डोम तत्व आईडी के युग्मन नियंत्रक से बचते हैं।

नमूना कोड निर्देश:

gbndirectives.directive('focusOnCondition', ['$timeout',
    function ($timeout) {
        var checkDirectivePrerequisites = function (attrs) {
          if (!attrs.focusOnCondition && attrs.focusOnCondition != "") {
                throw "FocusOnCondition missing attribute to evaluate";
          }
        }

        return {            
            restrict: "A",
            link: function (scope, element, attrs, ctrls) {
                checkDirectivePrerequisites(attrs);

                scope.$watch(attrs.focusOnCondition, function (currentValue, lastValue) {
                    if(currentValue == true) {
                        $timeout(function () {                                                
                            element.focus();
                        });
                    }
                });
            }
        };
    }
]);

एक संभावित उपयोग

.controller('Ctrl', function($scope) {
   $scope.myCondition = false;
   // you can just add this to a radiobutton click value
   // or just watch for a value to change...
   $scope.doSomething = function(newMyConditionValue) {
       // do something awesome
       $scope.myCondition = newMyConditionValue;
  };

});

एचटीएमएल

<input focus-on-condition="myCondition">

1
तब क्या होगा जब myCondition$ स्कोप वैरिएबल पहले से ही सही पर सेट हो गया है और तब उपयोगकर्ता किसी अन्य तत्व पर ध्यान केंद्रित करने का विकल्प चुनता है, क्या आप अभी भी फ़ोकस को तब रीग्रिग कर सकते हैं जब myConditionवह पहले से ही सत्य है, आपका कोड विशेषता के लिए परिवर्तन देखता है focusOnConditionलेकिन यह ट्रिगर नहीं होगा जब जिस मूल्य को आप बदलने की कोशिश करते हैं वह अभी भी वैसा ही है।
रायबेलार

मैं हम दोनों रेडियो बटन है, और हम सही या गलत मूल्य के आधार पर करने के लिए ध्वज टॉगल, नमूना अद्यतन करने के लिए जा रहा हूँ हमारे मामले में, तुम सिर्फ myCondition झंडा सही या गलत का बदल सकता है
Braulio

एक सामान्य समाधान की तरह लगता है। आईडी के आधार पर बेहतर है। मुझें यह पसंद है।
मोर्टब

यदि कोई अन्य व्यक्ति यह कोशिश करता है और यह काम नहीं करता है, तो मुझे element.focus () बदलना होगा; को तत्व [0] .focus ();
एड्रियन कैर

1
यह समाधान ऊपर स्थित आईडी-आधारित हैक की तुलना में बहुत अधिक 'कोणीय तरीका' है।
14

11

जब भी संभव हो मैं DOM लुक्स, घड़ियों और वैश्विक उत्सर्जकों से बचना पसंद करता हूं, इसलिए मैं अधिक प्रत्यक्ष दृष्टिकोण का उपयोग करता हूं। एक साधारण फ़ंक्शन को निर्दिष्ट करने के लिए एक निर्देश का उपयोग करें जो निर्देश तत्व पर केंद्रित है। फिर उस फ़ंक्शन को कॉल करें जहां भी नियंत्रक के दायरे में आवश्यक हो।

इसे स्कोप में संलग्न करने के लिए एक सरल तरीका है। कंट्रोलर-सिंटैक्स को संभालने के लिए पूरा स्निपेट देखें।

निर्देशक:

app.directive('inputFocusFunction', function () {
    'use strict';
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            scope[attr.inputFocusFunction] = function () {
                element[0].focus();
            };
        }
    };
});

और HTML में:

<input input-focus-function="focusOnSaveInput" ng-model="saveName">
<button ng-click="focusOnSaveInput()">Focus</button>

या नियंत्रक में:

$scope.focusOnSaveInput();

इस दृष्टिकोण के कारण के बारे में अधिक स्पष्टीकरण प्रदान करने और नियंत्रक-उपयोग के लिए कोड स्निपेट का विस्तार करने के लिए संपादित किया गया।


यह बहुत अच्छा है, और मेरे लिए अच्छा काम कर रहा है। लेकिन अब मेरे पास उपयोग करने वाले इनपुट का एक सेट है ng-repeat, और मैं केवल पहले एक के लिए फोकस फ़ंक्शन सेट करना चाहता हूं। किसी भी विचार कैसे मैं सशर्त रूप से उदाहरण के लिए <input>आधार पर एक फोकस फ़ंक्शन सेट कर सकता हूं $index?
गैरेट विल्सन

खुशी है कि यह उपयोगी है। मेरी कोणीय 1 एक छोटी सी जंग है, लेकिन आपको इनपुट को एक और विशेषता जोड़ने में सक्षम होना चाहिए, जैसे assign-focus-function-if="{{$index===0}}", और फिर निर्देश के बाहर निकलने की पहली पंक्ति के रूप में फ़ंक्शन को असाइन करने से पहले जल्दी से अगर यह सच नहीं है: if (attr.assignFocusFunctionIf===false) return; नोट मैं जाँच कर रहा हूँ यदि यह स्पष्ट रूप से falseगलत नहीं है और यह निर्देश अभी भी काम करेगा यदि यह विशेषता परिभाषित नहीं है।
cstricklan

कंट्रोलर-जैसा कि लॉश के साथ बहुत सरल है। _.set(scope, attributes.focusOnSaveInput, function() { element.focus(); })
एटमॉस्क सिप

9

तुम कोशिश कर सकते हो

angular.element('#<elementId>').focus();

उदाहरण के लिए।

angular.element('#txtUserId').focus();

मेरे लिए यह काम कर रहा है।


4
नोट: यह केवल तभी काम करेगा जब पूर्ण jQuery का उपयोग करने के बजाय कोणीय में एम्बेडेड jqLite पर निर्भर हो। देखें docs.angularjs.org/api/ng/function/angular.element
जॉन Rix

4
यह ऐसा करने का jQuery तरीका है, कोणीय तरीका नहीं है। प्रश्न विशेष रूप से यह पूछता है कि इसे कोणीय तरीके से कैसे किया जाए।
माफ करना

4

एक अन्य विकल्प यह होगा कि आप अपने निर्देश को ध्यान केंद्रित करने के लिए कोणीय के अंतर्निहित पब-उप वास्तुकला का उपयोग करें। अन्य दृष्टिकोणों के समान, लेकिन यह तब सीधे एक संपत्ति से जुड़ा नहीं होता है, और इसके बजाय यह सुन रहा है कि यह किसी विशेष कुंजी के लिए गुंजाइश है।

निर्देशक:

angular.module("app").directive("focusOn", function($timeout) {
  return {
    restrict: "A",
    link: function(scope, element, attrs) {
      scope.$on(attrs.focusOn, function(e) {
        $timeout((function() {
          element[0].focus();
        }), 10);
      });
    }
  };
});

HTML:

<input type="text" name="text_input" ng-model="ctrl.model" focus-on="focusTextInput" />

नियंत्रक:

//Assume this is within your controller
//And you've hit the point where you want to focus the input:
$scope.$broadcast("focusTextInput");

3

मैंने एक अभिव्यक्ति का उपयोग करना पसंद किया। यह मुझे एक बटन पर ध्यान केंद्रित करने जैसा सामान देता है जब एक क्षेत्र वैध होता है, एक निश्चित लंबाई तक पहुंचता है, और निश्चित रूप से लोड होने के बाद।

<button type="button" moo-focus-expression="form.phone.$valid">
<button type="submit" moo-focus-expression="smsconfirm.length == 6">
<input type="text" moo-focus-expression="true">

एक जटिल रूप पर यह ध्यान केंद्रित करने के उद्देश्यों के लिए अतिरिक्त गुंजाइश चर बनाने की आवश्यकता को कम करता है।

Https://stackoverflow.com/a/29963695/937997 देखें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.