एनजी-मॉडल नियंत्रक मूल्य को अपडेट नहीं करता है


270

शायद मूर्खतापूर्ण सवाल है, लेकिन मेरे पास सरल इनपुट और बटन के साथ मेरा html फॉर्म है:

<input type="text" ng-model="searchText" />
<button ng-click="check()">Check!</button>
{{ searchText }}

फिर कंट्रोलर (टेम्पलेट और कंट्रोलर को रूटप्रोवाइडर से बुलाया जाता है):

$scope.check = function () {
    console.log($scope.searchText);
}

मैं बटन को क्लिक करते समय कंसोल में अपडेट किए गए दृश्य को सही ढंग से अपरिभाषित क्यों देखता हूं?

धन्यवाद!

अपडेट: ऐसा लगता है कि मैंने वास्तव में उस मुद्दे को हल कर लिया है (पहले कुछ वर्कअराउंड के साथ आना पड़ा था): केवल मेरी संपत्ति का नाम बदलकर से searchTextकरना था search.text, फिर $scope.search = {};नियंत्रक और वॉइला में खाली वस्तु को परिभाषित करें ... पता नहीं क्यों यह काम कर रहा है हालांकि ;]


क्या आप सुनिश्चित हैं कि आप दस्तावेज़ के इस हिस्से में इस नियंत्रक का उपयोग कर रहे हैं? क्या आप एक न्यूनतम असफल उदाहरण पोस्ट कर सकते हैं?
wroniasty

1
हाँ, 100% यकीन है कि नियंत्रक ठीक है, कि इस मुद्दे को ... मुझे परिचित हो रहा है हैरानी की बात है यह काम करता है जब मैं से संपत्ति का नाम बदलने searchTextके लिए search.text, किसी भी विचार क्यों ??
रसायन विद्या

4
@ आर्थर: यह थोड़े स्पष्ट नहीं है, लेकिन एनजी-मॉडल केवल आपके विचार में एक प्रकार का स्थानीय चर बोलता है, वहीं अगर आप इसे इस तरह रखना चाहते हैं तो आपको इसे चेक () फ़ंक्शन में पास करना होगा, जैसे: चेक ( searchText) और आपका कंट्रोलर तब इसे पहचान लेगा। आशा है कि यह मदद करता है
रसायन विद्या

3
रिकॉर्ड के लिए, यह वर्तनी voila, नहीं vuala, wolla, आदि
दान Bechard

3
मुझे लगता है कि आप जिस उत्तर की तलाश कर रहे हैं वह stackoverflow.com/a/14049482/1217913
Willa

जवाबों:


71

संस्करण के रूप में नियंत्रक (अनुशंसित)

यहाँ टेम्पलेट

<div ng-app="example" ng-controller="myController as $ctrl">
    <input type="text" ng-model="$ctrl.searchText" />
    <button ng-click="$ctrl.check()">Check!</button>
    {{ $ctrl.searchText }}
</div>

जेएस

angular.module('example', [])
  .controller('myController', function() {
    var vm = this;
    vm.check = function () {
      console.log(vm.searchText);
    };
  });

एक उदाहरण: http://codepen.io/Damax/pen/rjawoO

सबसे अच्छा अंगुली 2.x या कोणीय 1.5 या ऊपरी के साथ घटक का उपयोग करना होगा

########

पुराना तरीका (अनुशंसित नहीं)

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

इसे अपने मार्कअप में आज़माएं

<input type="text" ng-model="searchText" />
<button ng-click="check(searchText)">Check!</button>
{{ searchText }}

और यह आपके नियंत्रक में है

$scope.check = function (searchText) {
    console.log(searchText);
}

17
यह केवल एकतरफा काम करता है ... यदि आप मूल्य बदलना चाहते हैं तो क्या होगा searchText?
cdmckay

199
यह भी "क्यों?" का जवाब नहीं है सवाल।
cdmckay

4
क्या होगा अगर मैं किसी भी बटन का उपयोग नहीं करना चाहता हूं? उदाहरण के लिए मुझे प्रवेश करने की आवश्यकता है
danikoren

2
Saniko => में प्रवेश पर प्रस्तुत करने के लिए, आप प्रपत्र टैग का उपयोग करना चाहिए और उस पर एनजी के लिये भेज ( docs.angularjs.org/api/ng.directive:ngSubmit )
Damax

1
@ HP का ४११ इसलिए है क्योंकि एक स्ट्रिंग एक आदिम है। जब एंगुलर वैल्यू असाइन करता है तो यह पॉइंटर को वैल्यू में बदल देता है, इसलिए कंट्रोलर पुराने वैल्यू को देखता है क्योंकि इसमें वैल्यू के लिए पुराना पॉइंटर होता है।
डैमैक्स

620

"यदि आप एनजी-मॉडल का उपयोग करते हैं, तो आपको वहां एक डॉट रखना होगा।"
अपने मॉडल को एक object.property को इंगित करें और आप जाने के लिए अच्छा होगा।

नियंत्रक

$scope.formData = {};
$scope.check = function () {
  console.log($scope.formData.searchText.$modelValue); //works
}

खाका

<input ng-model="formData.searchText"/>
<button ng-click="check()">Check!</button>

यह तब होता है जब चाइल्ड स्कोप खेल में होते हैं - जैसे बाल मार्ग या एनजी-रिपीट। चाइल्ड-स्कोप इसका अपना मूल्य बनाता है और एक नाम संघर्ष के रूप में यहाँ चित्रित किया गया है :

इस वीडियो क्लिप को और देखें: https://www.youtube.com/watch?v=SBwoFkRjZvE&t=3m15s


94
यही असली जवाब है।
केसलर्ट

16
@ कैटफ़िश, प्रोटोटाइप विरासत के साथ, जब भी आप बाल संपत्ति को लिखते हैं, तो मूल संपत्ति का संदर्भ / कनेक्शन मौजूद नहीं रहता है। जिस तरह से कोणीय स्कोप मॉडल, यदि आपके पास डॉट नहीं है, तो आपके बच्चे के दायरे में एक नई संपत्ति बनती है। यह वीडियो इसे और अधिक विस्तार से बताता है: youtube.com/watch?v=ZhfUv0spHCY&feature=youtu.be&t=30m
विल स्टेटन

1
ग्रेसिया बॉस। यह सच है! हालाँकि, यह एक सुसंगत विचित्रता के रूप में प्रतीत नहीं होता है क्योंकि Ionic की रूपरेखा के साथ प्रयोग करने पर ही मुझे समस्या आती है
डॉन बैरी

6
@ user3677331 यह एक डॉट के बिना ठीक काम करता है जब तक कि आपके पास एक बच्चा गुंजाइश नहीं है जो उससे बात करने की कोशिश करता है (उदाहरण के लिए एनजी-दोहराने के भीतर एक आइटम की तरह)। मान लें कि आपका मॉडल नाम "फोन" था, आपका चाइल्ड स्कोप "फोन" बनाता है, फिर आपको स्कोप संघर्ष होता है क्योंकि चाइल्ड-स्कोप में "फोन" वैरिएबल होता है और इस तरह पेरेंट स्कोप पर "फोन" नहीं पहुंच सकता। जबकि अगर चाइल्ड स्कोप user.phone बनाता है, तो इसे माता-पिता की उपयोगकर्ता ऑब्जेक्ट में जोड़ा जाएगा, इसलिए दोनों स्कोप एक ही ऑब्जेक्ट की ओर इशारा कर रहे हैं
विल स्टर्न

3
बहुत मददगार। मुझे यकीन नहीं था कि मैं एक अपेक्षाकृत अस्पष्ट प्रश्न का उत्तर पाऊंगा, लेकिन यह मृत था।
कोडमनिएक

57

AngularJS बुक p.19 के साथ मास्ट्रिंग वेब एप्लिकेशन डेवलपमेंट में, यह लिखा है कि

गुंजाइश के गुणों के लिए प्रत्यक्ष बाइंडिंग से बचें। ऑब्जेक्ट के गुणों के लिए दो-तरफ़ा डेटा बाइंडिंग (एक दायरे पर उजागर) एक पसंदीदा दृष्टिकोण है। अंगूठे के एक नियम के रूप में, आपको एनजी-मॉडल निर्देश के लिए प्रदान की गई अभिव्यक्ति में एक डॉट होना चाहिए (उदाहरण के लिए, एनजी-मॉडल = "thing.name")।

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


2
इस संदर्भ के लिए धन्यवाद। मैं इसे एनजी-मॉडल से संबंधित एक दिलचस्प बिंदु मानता हूं।
किंग्स

44

कार्यों के thisबजाय का उपयोग करना $scope

function AppCtrl($scope){
  $scope.searchText = "";
  $scope.check = function () {
    console.log("You typed '" + this.searchText + "'"); // used 'this' instead of $scope
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app>
  <div ng-controller="AppCtrl">
    <input ng-model="searchText"/>
    <button ng-click="check()">Write console log</button>
  </div>
</div>

संपादित करें: इस उत्तर को लिखते समय, मेरे पास इससे कहीं अधिक जटिल स्थिति थी। टिप्पणियों के बाद, मैंने इसे समझने की कोशिश की कि यह क्यों काम करता है, लेकिन भाग्य नहीं। मुझे लगता है कि किसी भी तरह (वास्तव में पता नहीं क्यों) एक नया चाइल्ड स्कोप उत्पन्न होता है और thisउस स्कोप को संदर्भित करता है। लेकिन अगर $scopeइसका उपयोग किया जाता है, तो यह वास्तव में जावास्क्रिप्ट की लेक्सिकल स्कोप फीचर की वजह से पेरेंट $ स्कोप को संदर्भित करता है ।

बहुत अच्छा होगा यदि किसी को यह समस्या इस तरह से हो और हमें सूचित करे।


निर्दोष, आप एक प्रतिभाशाली हैं
fjcero

1
$scopeएक नया दायरा बनाने के लिए संलग्न कार्यों की तरह दिखता है (यानी फ़ंक्शन में check(), thisएक गुंजाइश है कि एक बच्चा गुंजाइश है $scope)। ऐसा क्यों है? क्या आप कुछ स्पष्टीकरण दे सकते हैं?
क्सुन यांग

1
मुझे इस मामले में '$ स्कोप' के बजाय 'इस' का उपयोग क्यों करना चाहिए? क्योंकि इसने मेरे पिछले प्रोजेक्ट में $ स्कोप का उपयोग करने का काम किया था लेकिन इस बार एक ही चीज़ $ स्कोप का उपयोग करके काम नहीं करती है। लेकिन But इस ’ने काम किया है। ऐसा क्यों है?
राशेदुल .ubel

यह काम करता है, लेकिन अगर आप कहते हैं this.searchText = "something else"या भले ही $scope.searchText = "something else", यह दृश्य को अपडेट नहीं करता है। क्या आप इस समस्या की व्याख्या कर सकते हैं?
श्री

यह होना चाहिए। मैंने इसे ऊपर दिए गए कोड का उपयोग करके देखा, इसने दृश्य को अपडेट किया।
फेयज

13

मेरे पास एक ही समस्या थी और यह मेरे नियंत्रक के शीर्ष पर सबसे पहले रिक्त वस्तु की घोषणा नहीं करने के कारण था:

$scope.model = {}

<input ng-model="model.firstProperty">

आशा है कि यह आपके लिए काम करेगा!


10

मैं एक ही मुद्दे पर आया था जब एक गैर-तुच्छ दृष्टिकोण (वहाँ नेस्टेड स्कोप) के साथ काम कर रहा था। और अंत में पता चला कि यह एक ज्ञात मुश्किल बात है जब जावा स्क्रिप्ट के प्रोटोटाइप-आधारित विरासत की प्रकृति के कारण AngularJS एप्लिकेशन को विकसित करना। AngularJS नेस्टेड स्कोप इस तंत्र के माध्यम से बनाए जाते हैं। और एनजी-मॉडल से बनाया गया मान बच्चों के दायरे में रखा जाता है, माता-पिता की गुंजाइश (शायद नियंत्रक में अंतःक्षिप्त एक) को मान नहीं कहा जाएगा, मान किसी भी संपत्ति को उसी नाम से छाया देगा, जो मूल दायरे में परिभाषित नहीं है, यदि डॉट का उपयोग नहीं किया गया है एक प्रोटोटाइप संदर्भ पहुंच को लागू करने के लिए। अधिक विवरण के लिए, इस मुद्दे, http://egghead.io/video/angularjs-the-dot/ और इस पर आने वाली टिप्पणियों को दर्शाने के लिए ऑनलाइन विशिष्ट वीडियो देखें ।


6

इस फिडेल पर एक नजर डालें http://jsfiddle.net/ganarajpr/MSjqL/

मेरे पास (मुझे लगता है!) ठीक वही किया जो आप कर रहे थे और यह काम करने लगता है। क्या आप देख सकते हैं कि आपके लिए यहां क्या काम नहीं हो रहा है?


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

मुझे सच में यकीन नहीं है कि यह आपके लिए काम क्यों नहीं करता है। यदि आप इस मुद्दे को एक बेला में अलग कर सकते हैं, तो मुझे लगता है कि कोई व्यक्ति आपको एक बेहतर जवाब देने में सक्षम होगा :)
ganaraj

ठीक है, अभी काम खत्म कर दूंगा, लेकिन कल शाम या बाद में यह सुनिश्चित करूंगा कि जयकार! मेरे ctrl के नाम को रखने के तरीके में कोई समस्या हो सकती है, हम देखेंगे ...
रसायन

6

चूंकि किसी ने भी इस बात का उल्लेख नहीं किया है, इसलिए समस्या $parentको बाध्य संपत्ति में जोड़कर हल किया जा सकता है

<div ng-controller="LoginController">
    <input type="text" name="login" class="form-control" ng-model="$parent.ssn" ng-pattern="/\d{6,8}-\d{4}|\d{10,12}/" ng-required="true" />
    <button class="button-big" type="submit" ng-click="BankLogin()" ng-disabled="!bankidForm.login.$valid">Logga in</button>
</div>

और नियंत्रक

app.controller("LoginController", ['$scope', function ($scope) {
    $scope.ssn = '';

    $scope.BankLogin = function () {
        console.log($scope.ssn); // works!
    };
}]);

जवाब के लिए धन्यवाद, हालांकि यह काम कर रहा है? यह आदर्श रूप से एक ही स्कोप तत्व पर काम करना चाहिए न कि माता-पिता के लिए?
V31

5

मेरे लिए मेरे डेटा को किसी ऑब्जेक्ट (यहां "डेटा") में स्टॉक करके समस्या हल की गई थी।

NgApp.controller('MyController', function($scope) {

   $scope.my_title = ""; // This don't work in ng-click function called

   $scope.datas = {
      'my_title' : "",
   };

   $scope.doAction = function() {
         console.log($scope.my_title); // bad value
         console.log($scope.datas.my_title); // Good Value binded by'ng-model'
   }
   

});

मुझे आशा है कि यह मदद करेगा


3
विषय से थोड़ा हटकर, लेकिन 'डेटा' 'डेटम' के लिए एक बहुवचन शब्द है
थथुरी

@ तेथाकुरी और "डेटम" में "डेट" है, इसलिए मुझे यकीन है कि या तो इसका उपयोग नहीं किया जाएगा: पी
एपिकपांडर्सफेयर


2

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

समस्या को हल करने के लिए, रूट-लोडेड HTML सामग्री के भीतर एक समर्पित नियंत्रक का उपयोग करें।


2

आप ऐसा कर सकते हैं कि ng-keypressइनपुट पाठ के ng-clickलिए और आइकन के लिए दर्ज करें:

<input type="text" ng-model="searchText" ng-keypress="keyEnter(this,$event)" />
<button ng-click="check(searchText)">Check!</button>

in the controller
$scope.search = function (searchText) {
        console.log(searchText);
    }
    $scope.keyEnter = function (serachText,$event) {
        var keyCode = $event.which || $event.keyCode;
        if (keyCode === 13) {//KeyCode for Enter key
           console.log(searchText);
        }
    }

2

मुझे भी यही समस्या थी।
उचित तरीका एक वस्तु के अंदर एक संपत्ति होने के लिए 'सर्चटेक्स्ट' सेट करना होगा।

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

<input type="text" ng-model="searchText" value={{searchText}} />

इस तरह से मूल्य केवल '$ गुंजाइश.searchText' मान पर सेट है और इनपुट मूल्य में परिवर्तन होने पर इसे अपडेट किया जा रहा है।

मुझे पता है कि यह एक वर्कअराउंड है, लेकिन इसने मेरे लिए काम किया ।।


2

मैं एक ही समस्या का सामना कर रहा था ... मेरे लिए काम करने वाला संकल्प इस कीवर्ड का उपयोग करना है ..........

चेतावनी (this.ModelName);

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