क्या मैं कंट्रोलर में फॉर्म एक्सेस कर सकता हूं?


152

मैं वर्तमान में निम्नलिखित का उपयोग कर रहा हूँ।

$scope.$$childHead.customerForm[firstName], ताकि:

<form name="customerForm">
  <input type="text" name="firstName" 
         ng-model="data.customer.firstName" 
         tabindex="1"  
         ng-disabled="!data.editable" 
         validationcustomer />
</form>

लेकिन यह केवल क्रोम में काम करता है। अब मैंने निम्नलिखित कोशिश की:

$scope.editCustomerForm[firstName], ताकि:

<form name="customerForm" ng-model="editCustomerForm">
  <input type="text" name="firstName" 
         ng-model="data.customer.firstName" tabindex="1"  
         ng-disabled="!data.editable" 
         validationcustomer />
</form>

जो काम नहीं करता है। ध्यान दें मेरा फॉर्म एक फाउंडेशन टैब के अंदर है। मैं कैसे पहुंच सकता हूं firstName?

संपादित करें : ऐसा लगता formहै कि scopeजब यह एक फाउंडेशन टैब के अंदर है , तो इसमें जोड़ा नहीं जाता है ।

किसी को भी इस के लिए एक समाधान मिल गया है?

जवाबों:


210

हालांकि अन्य टिप्पणियों में कहा गया था कि मुझे लगा कि "कंट्रोलर अस" सिंटैक्स का उपयोग करने वालों के लिए मैं इसे थोड़ा सा बदल दूंगा:

<div ng-controller="MyController as ctrl">

<form name="ctrl.myForm">
    ...inputs
    Dirty? {{ctrl.myForm.$dirty}}

    <button ng-click="ctrl.saveChanges()">Save</button>
</form>

</div>

फिर आप अपने कोड में फॉर्मकंट्रोलर का उपयोग कर सकते हैं जैसे:

function MyController () {
    var vm = this;
    vm.saveChanges = saveChanges;

    function saveChanges() {

       if(vm.myForm.$valid) { 
            // Save to db or whatever.
            vm.myForm.$setPristine();
       }
}

जहां तक ​​मैं देख सकता हूं, टेम्प्लेट "saveChanges" विधि को कॉल नहीं कर सकता है, क्योंकि यह टेम्पलेट के संपर्क में नहीं है
Spock

2
"SaveChanges" विधि को जावास्क्रिप्ट की पंक्ति 3 में उजागर किया गया है या क्या मैं गलतफहमी हूं?
स्लोपापा

3
यह अच्छा है क्योंकि इसका मतलब है कि आप पूरे $ स्कोप को इंजेक्ट करने से बच सकते हैं, जो कि मेरी राय में क्लीनर है
72GM

2
आप इसे चमेली में कैसे परीक्षण करते हैं? मेरे विचार में, vm.myForm अपरिभाषित है
bahrieinn

1
यह आधिकारिक डॉक्स में 1.5.X के लिए ध्यान दिया जाना चाहिए जो कि घटक और es6 करने का तरीका है। धन्यवाद सर
मतानिको २

91

आप फॉर्म को कुछ ऑब्जेक्ट से जोड़ सकते हैं जो कि पैरेंट कंट्रोलर में परिभाषित होता है। फिर आप बच्चे के दायरे से भी अपने रूप तक पहुँच सकते हैं।

जनक नियंत्रक

$scope.forms = {};

एक बच्चे के दायरे में कुछ टेम्पलेट

<form name="forms.form1">
</form>

समस्या यह है कि प्रपत्र को उस क्षण में परिभाषित नहीं किया जाना चाहिए जब नियंत्रक में कोड निष्पादित किया जाता है। तो आपको कुछ इस तरह से करना होगा

$scope.$watch('forms.form1', function(form) {
  if(form) {
    // your code...
  }
});

10
मैं सुझाव देता हूं कि var watcher = $scope.$watcherयदि आप वॉचर () को वॉच अनबाइंड करने के लिए कहेंगे, तो आप उसके अंदर और उपयोग कर सकते हैं। इस बनाता है एक 1 समय घड़ी ताकि आप नहीं देख रहे हैं कि हर पचाने के बाद यह सेट किया गया है
willJk

91

यदि आप सत्यापन उद्देश्यों के लिए नियंत्रक को फ़ॉर्म पास करना चाहते हैं, तो आप इसे जमा करने की विधि के तर्क के रूप में पास कर सकते हैं। प्रपत्र नाम का उपयोग करें, इसलिए मूल प्रश्न के लिए यह कुछ इस तरह होगा:

<button ng-click="submit(customerForm)">Save</button>

13
भविष्य पाठकों के लिए स्पष्ट करने के लिए करता है, तो कहते हैं कि आपके प्रपत्र नामित / इस के समान परिभाषित किया गया है <form name="myform"></form>, या यहाँ तक <div ng-form name="myform"></div>है, तो अपने क्लिक करें घटना के रूप में इस प्रकार होगा: ng-click="submit(myform)"। फिर आप अपने क्लिक फंक्शन में कोणीय फॉर्म ऑब्जेक्ट को एक्सेस कर सकते हैं जैसे: $scope.submit = function (form) { if (form.$valid) {आदि
Matty J

मुझे यहां एक समस्या है - मान लीजिए कि फ़ॉर्म में एक ड्रॉपडाउन सूची है। उपरोक्त पद्धति का उपयोग करने से मुझे केवल दृश्य मान मिलता है, न कि सटीक मूल्य जो मुझे चाहिए। या मैं कुछ भी गलत कर रहा हूँ, एक बेला जोड़ देगा।
15

82

उत्तर के लिए थोड़ा देर से लेकिन निम्नलिखित विकल्प के साथ आया था। यह मेरे लिए काम कर रहा है लेकिन निश्चित नहीं है कि यह सही तरीका है या नहीं।

मेरे विचार में मैं यह कर रहा हूँ:

<form name="formName">
    <div ng-init="setForm(formName);"></div>
</form>

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

$scope.setForm = function (form) {
    $scope.myForm = form;
}

अब ऐसा करने के बाद मैंने अपने कंट्रोलर वैरिएबल में अपना फॉर्म प्राप्त कर लिया है $scope.myForm


1
केवल एक चीज जो मैं इसमें जोड़ूंगा, वह यह सुनिश्चित करना है कि यह फ़ॉर्म के निचले भाग में है।
smb

<Div ng-init = "setForm (formName) की स्थिति;"> </ div> कोई फर्क नहीं पड़ता। बस सावधान रहना चाहिए कि यह रूप में है।
वाकास

1
अच्छा है, लेकिन मैं एक सरल समाधान पसंद करूंगा: एनजी-इनिट = "$ पैरेंट ।myForm = formName" नियंत्रक को बदलने की आवश्यकता के बारे में ध्यान दें: यह केवल प्रत्यक्ष नियंत्रक के साथ काम कर रहा है, ऊपर दिए गए समाधान के विपरीत
मास्टिलिन

अन्य तरीकों की कोशिश करने के बाद, मैं इस पर बस गया क्योंकि यह nameविशेषता को वैसा होने की अनुमति देता है जैसा मैं चाहता हूं। अन्य डमी-ऑब्जेक्ट समाधानों के साथ समस्या यह है कि यदि इस घटक का उपयोग किसी अन्य घटक में एनजी-फॉर्म के साथ किया जाता है, तो अन्य एनजी-फॉर्म इस फॉर्म नाम का शाब्दिक उपयोग करता है। तो यह एक स्ट्रिंग के साथ एक फ़ील्ड होगा, जिसमें "dummy.myForm" नाम का स्ट्रिंग-नेस्टेड गुण नहीं है, मुझे यह अस्वीकार्य लगा।
तुलसी

मैंने कंट्रोलर सिंटैक्स (मैं $ mdDialog के साथ काम कर रहा हूं) का उपयोग करने के लिए कई बार कोशिश की और असफल रहा। अंत में इसके लिए समझौता किया और इसने बहुत अच्छा काम किया। केवल ध्यान दें कि किसी भी कंट्रोलर इनिशियलाइज़ेशन को $ टाइमआउट पर चलाने की जरूरत है क्योंकि फॉर्म तब उपलब्ध नहीं होता जब कंट्रोलर पहले चलता है
पीटर निक्से

22

अपने नियंत्रक में फ़ॉर्म को एक्सेस करने में सक्षम होने के लिए, आपको इसे डमी स्कोप ऑब्जेक्ट में जोड़ना होगा।

कुछ इस तरह $scope.dummy = {}

आपकी स्थिति के लिए इसका मतलब कुछ इस तरह होगा:

<form name="dummy.customerForm">

आपके कंट्रोलर में आप फॉर्म को एक्सेस कर पाएंगे:

$scope.dummy.customerForm

और आप सामान की तरह कर पाएंगे

$scope.dummy.customerForm.$setPristine()

विकी लिंक

होने '।' आपके मॉडल में यह सुनिश्चित होगा कि प्रोटोटाइप विरासत में मिला है। इसलिए, <input type="text" ng-model="someObj.prop1">इसके बजाय का उपयोग करें<input type="text" ng-model="prop1">

यदि आप वास्तव में एक आदिम का उपयोग करना चाहते हैं, तो दो वर्कअराउंड हैं:

1. $ पालक का उपयोग करें। यह बच्चे की गुंजाइश को अपनी संपत्ति बनाने से रोक देगा। 2. माता-पिता के दायरे पर एक समारोह निर्धारित करें, और इसे बच्चे से बुलाएं, माता-पिता के लिए आदिम मूल्य पारित करना (हमेशा नहीं)


फॉर्म बाइंडिंग को परिभाषित करने के लिए प्रभावी क्षेत्र कहां है?
गस क्रॉफोर्ड

इसके लायक है कि dummy.customerFormअपरिभाषित होगा जब तक की शर्तों ng-ifको पूरा कर रहे हैं जब तक फार्म तत्व ng-ifउस पर एक सशर्त होना चाहिए
haxxxton

22

यह उत्तर थोड़ा देर से है, लेकिन मैं एक समाधान पर ठोकर खाई है जो सब कुछ बहुत आसान बनाता है।

यदि आप कंट्रोलर सिंटैक्स का उपयोग कर रहे हैं तो आप वास्तव में फॉर्म नाम को सीधे अपने कंट्रोलर को सौंप सकते हैं और फिर इसे अपने "इस" वेरिएबल से रेफर कर सकते हैं। यहाँ मैंने इसे अपने कोड में कैसे किया है:

मैंने यूआई-राउटर के माध्यम से नियंत्रक को कॉन्फ़िगर किया (लेकिन आप ऐसा कर सकते हैं जो आप चाहते हैं, यहां तक ​​कि HTML में भी सीधे कुछ <div ng-controller="someController as myCtrl">इस तरह से ) यह वही है जो एक यूआई-राउटर कॉन्फ़िगरेशन में दिख सकता है:

views: {
            "": {
                templateUrl: "someTemplate.html",
                controller: "someController",
                controllerAs: "myCtrl"
            }
       }

और फिर HTML में, आप फॉर्म नाम को "कंट्रोलर" के रूप में सेट करते हैं। "नाम" जैसे:

<ng-form name="myCtrl.someForm">
    <!-- example form code here -->
    <input name="firstName" ng-model="myCtrl.user.firstName" required>
</ng-form>

अब अपने नियंत्रक के अंदर आप बहुत आसानी से ऐसा कर सकते हैं:

angular
.module("something")
.controller("someController",
    [
       "$scope",
        function ($scope) {
            var vm = this;
            if(vm.someForm.$valid){
              // do something
            }
    }]);

2
हालाँकि यह ज्यादातर एक ही तकनीक है जैसा कि कई अन्य उत्तर सुझाते हैं, यह सबसे अच्छा बदलाव है और इसे स्वीकार किए जाने वाला उत्तर होना चाहिए, खासकर जब से हर कोई अभी भी नियंत्रक का उपयोग करता है।
सेमीकोलन

6

हां, आप कंट्रोलर में एक फॉर्म एक्सेस कर सकते हैं (जैसा कि डॉक्स में बताया गया है )।

सिवाय जब आपका फॉर्म कंट्रोलर के दायरे में परिभाषित हो और इसके बजाय चाइल्ड स्कोप में परिभाषित किया गया हो।

मूल रूप से, कुछ कोणीय निर्देश, जैसे ng-if, ng-repeatया ng-include, एक अलग बाल गुंजाइश बनाएंगे। तो क्या कोई scope: {}संपत्ति परिभाषित के साथ कोई कस्टम निर्देश होगा । शायद, आपके नींव घटक भी आपके रास्ते में हैं।

टैग के ng-ifआस-पास एक सरल का परिचय देते समय मुझे यही समस्या थी <form>

अधिक जानकारी के लिए इन्हें देखें:

नोट: मेरा सुझाव है कि आप अपना प्रश्न पुनः लिखें। आपके प्रश्न का उत्तर हां है लेकिन आपकी समस्या थोड़ी अलग है:

क्या मैं कंट्रोलर से चाइल्ड स्कोप में फॉर्म एक्सेस कर सकता हूं?

जिस पर जवाब बस यही होगा: नहीं


... जब तक आप अपने फॉर्म और कंट्रोलर सेट नहीं करते हैं, जैसा कि @ondrs के उत्तर (उपयोग $scope.forms = {}और name="forms.form1") में वर्णित है
marapet

कृपया खलीलरावण द्वारा आपके ऊपर दिए गए उत्तर को तुरंत देखें। आप $ स्कोप.फॉर्मनाम से फॉर्म को एक्सेस कर सकते हैं। वह एक काम करने का उदाहरण प्रदान करता है
micahblu

3

ng-model="$ctrl.formName"अपने फ़ॉर्म में विशेषता जोड़ें , और फिर नियंत्रक में आप प्रपत्र को अपने नियंत्रक के अंदर ऑब्जेक्ट के रूप में एक्सेस कर सकते हैंthis.formName


0

निश्चित रूप से आप स्कोप में फॉर्म तक नहीं पहुंच सकते। यह नहीं बना है। Html टेम्पलेट से DOM कंट्रोलर कंस्ट्रक्टर की तरह थोड़ा धीरे लोड होता है। यह देखने के लिए है कि डोम लोड होने तक और सभी निर्धारित दायरे तक देखना है!

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

$timeout(function(){
    console.log('customerForm:', $scope.customerForm);
    // everything else what you need
});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.