एनजी-मॉडल, एनजी-रिपीट और इनपुट के साथ कठिनाई


116

मैं उपयोगकर्ता को उपयोग करके ngRepeatऔर आइटम की सूची को संपादित करने की अनुमति देने की कोशिश कर रहा हूं ngModel। ( इस फिडेल को देखें ।) हालांकि, दोनों दृष्टिकोणों से मैंने विचित्र व्यवहार का नेतृत्व करने की कोशिश की है: एक मॉडल को अपडेट नहीं करता है, और दूसरा प्रत्येक कीडाउन पर फॉर्म को ब्लर करता है।

क्या मुझसे यहां कुछ गलत हो रहा है? क्या यह एक समर्थित उपयोग मामला नहीं है?

यहाँ फिडल से कोड है, सुविधा के लिए कॉपी किया गया:

<html ng-app>
    <head>
        <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/css/bootstrap-combined.min.css" rel="stylesheet">
    </head>
    <body ng-init="names = ['Sam', 'Harry', 'Sally']">
        <h1>Fun with Fields and ngModel</h1>
        <p>names: {{names}}</p>
        <h3>Binding to each element directly:</h3>
        <div ng-repeat="name in names">
            Value: {{name}}
            <input ng-model="name">                         
        </div>
        <p class="muted">The binding does not appear to be working: the value in the model is not changed.</p>
        <h3>Indexing into the array:</h3>
        <div ng-repeat="name in names">
            Value: {{names[$index]}}
            <input ng-model="names[$index]">                         
        </div>
        <p class="muted">Type one character, and the input field loses focus. However, the binding appears to be working correctly.</p>
    </body>
</html>


1
यह stackoverflow.com/questions/12977894/… से बहुत मिलता-जुलता है , लेकिन यहाँ दूसरा दृष्टिकोण नया है, इसलिए यह बिल्कुल डुप्लिकेट नहीं है। मैंने वहां एक विस्तृत उत्तर (आर्टेम के समान) प्रदान किया, जिसमें बताया गया कि कैसे बच्चे दोहराने के काम करते हैं।
मार्क राजकोक

चूँकि अंत में इस धागे को खोजने से पहले मुझे उचित मात्रा में गुगली की कीमत चुकानी पड़ती है, तो क्या मैं इसका नाम बदलकर sth कर सकता हूँ: "माता-पिता मॉडल को ngRepeat इनपुट से अपडेट नहीं किया गया" या "ngRepeat का उपयोग करते समय मॉडल अपडेट नहीं किया गया" या "ngRepeat" बाध्य नहीं है (माता-पिता) नमूना"? शायद आपके पास शीर्षक के लिए बेहतर विचार हैं?
वुकलूर

जवाबों:


120

यह एक बाध्यकारी मुद्दा लगता है।

सलाह आदिमता के लिए बाध्य नहीं है

आपका ngRepeatएक संग्रह के अंदर तार से अधिक पुनरावृत्ति है, जब यह बार-बार दोहराना वस्तुओं से अधिक होना चाहिए। अपनी समस्या को ठीक करने के लिए

<body ng-init="models = [{name:'Sam'},{name:'Harry'},{name:'Sally'}]">
    <h1>Fun with Fields and ngModel</h1>
    <p>names: {{models}}</p>
    <h3>Binding to each element directly:</h3>
    <div ng-repeat="model in models">
        Value: {{model.name}}
        <input ng-model="model.name">                         
    </div>

jsfiddle: http://jsfiddle.net/jaimem/rnw3u/5/


3
पहले हाइपरलिंक के लिए धन्यवाद, क्योंकि यह धब्बा / फोकस / झिलमिलाहट के नुकसान की व्याख्या करता है। मैं हमेशा सोचता था कि ऐसा क्यों हुआ।
मार्क राजकॉक

2
इसके लिए धन्यवाद, एक बहुत मदद की। फिर भी, आदिम लोगों के लिए बंधन को इमो होना चाहिए ...
डैनियल ग्रूसज़क

1
पुरानी पोस्ट लेकिन thnx, मुझे 'एनकैप्रेइट के अंदर मॉडल नहीं बदलने' की समस्या का पता लगाने के लिए कुछ समय लगा और यह आपकी सलाह थी कि आदिम से बंधे नहीं
स्टेफानोस चर्स

इसके अलावा: टाइप करते समय पूरी सूची को संशोधित न करें - मैं फंस गया। मैं परिवर्तनों के लिए संग्रह देख रहा था, और इसे एक समान प्रतिलिपि के साथ बदल रहा था - इसलिए भले ही मैं आदिम के लिए बाध्यकारी नहीं था, तत्वों को फिर से बनाया गया था।
z0r

71

कोणीय नवीनतम संस्करण (1.2.1) और ट्रैक द्वारा उपयोग करना $index। यह समस्या ठीक हो गई है

http://jsfiddle.net/rnw3u/53/

<div ng-repeat="(i, name) in names track by $index">
    Value: {{name}}
    <input ng-model="names[i]">                         
</div>

काम किया; कोई और अधिक संदर्भ नुकसान
दान ओचियाना

मैंने उसके लिए इतनी लंबी खोज की .... इतना आसान ... बस इतना छिपा हुआ। इसका उत्तर के रूप में दें!
एंड्रिया

oooooh, इसलिए एनजी-रिपीट में "ट्रैक बाय $ इंडेक्स" को जोड़ना भी "टिमटिमा" समस्या को ठीक करता है
boi_echos

43

आप एक मुश्किल स्थिति में आ जाते हैं जब यह समझना आवश्यक है कि कैसे NgModorCroller के साथ scopes , ngRepeat और ngModel काम के । इसके अलावा 1.0.3 संस्करण का उपयोग करने का प्रयास करें। आपका उदाहरण थोड़ा अलग तरीके से काम करेगा।

आप बस जेएम द्वारा प्रदान किए गए समाधान का उपयोग कर सकते हैं-

लेकिन अगर आप स्थिति से अधिक गहराई से निपटना चाहते हैं, तो आपको समझना होगा:

  • AngularJS कैसे काम करता है ;
  • स्कोप्स में एक पदानुक्रमित संरचना है;
  • ngRepeat हर तत्व के लिए नया स्कोप बनाता है;
  • ngRepeat अतिरिक्त जानकारी (hashKey) के साथ वस्तुओं का कैश बनाएँ; प्रत्येक घड़ी पर हर नए आइटम (जो कैश में नहीं है) के लिए कॉल करें। एनक्रिप्ट्री नए दायरे, डोम तत्व आदि का अधिक विस्तृत वर्णन करता है
  • वास्तविक मॉडल मूल्यों के साथ 1.0.3 ngModelController रेंडरर्स इनपुट से।

आपका उदाहरण "प्रत्येक तत्व को सीधे बांधना" कैसे काम करता है AngularJS 1.0.3 के लिए:

  • आप 'f'इनपुट में पत्र दर्ज करते हैं;
  • ngModelControllerआइटम क्षेत्र के लिए मॉडल में परिवर्तन (नाम सरणी नहीं बदला गया है) => name == 'Samf', names == ['Sam', 'Harry', 'Sally'];
  • $digest लूप शुरू किया जाता है;
  • ngRepeat'Samf'अपरिवर्तित नाम सरणी ( 'Sam') से मूल्य द्वारा आइटम गुंजाइश ( ) से मॉडल मूल्य को प्रतिस्थापित करता है ;
  • ngModelControllerवास्तविक मॉडल मूल्य ( 'Sam') के साथ रेंडरर्स इनपुट ।

आपका उदाहरण "सरणी में अनुक्रमण" कैसे काम करता है:

  • आप 'f'इनपुट में पत्र दर्ज करते हैं;
  • ngModelControllerनाम में आइटम परिवर्तन array=> `नाम == ['सैम', 'हैरी', 'सैली'];
  • $ पाचन लूप शुरू किया जाता है;
  • ngRepeat'Samf'कैश में नहीं मिल सकता है ;
  • ngRepeat नया दायरा बनाता है, नए इनपुट के साथ नया div एलिमेंट जोड़ता है (यही कारण है कि इनपुट फील्ड फोकस खो देता है - पुराने इनपुट के साथ पुराने div को नए इनपुट के साथ नए div द्वारा बदल दिया जाता है);
  • नए DOM तत्वों के लिए नए मान प्रदान किए गए हैं।

इसके अलावा, आप AngularJS Batarang का उपयोग करने का प्रयास कर सकते हैं और देख सकते हैं कि इनपुट के साथ div के दायरे में $ id कैसे बदलती है।


1.0.3 स्पष्टीकरण के लिए धन्यवाद। यह दिलचस्प है कि 1.0.3 में, "सीधे बाँध" मामले में, इनपुट फ़ील्ड टूटी हुई प्रतीत होती है, इस अर्थ में कि यह किसी भी परिवर्तन / टाइप किए गए इनपुट (कम से कम क्रोम में) को स्वीकार नहीं करता है। मुझे यकीन है कि हम निकट भविष्य में इसके बारे में काफी कुछ पोस्ट देखेंगे :) मुझे लगता है कि यह नया तरीका बेहतर है, क्योंकि यह अधिक स्पष्ट होगा कि कुछ गलत है।
मार्क राजकोक

6

यदि आपको हर की-स्ट्रोक से अपडेट करने के लिए मॉडल की आवश्यकता नहीं है, तो बस nameधब्बा घटना पर सरणी आइटम को अपडेट करें और अपडेट करें:

<div ng-repeat="name in names">
    Value: {{name}}
    <input ng-model="name" ng-blur="names[$index] = name" />
</div>

क्यों नहीं का उपयोग कर ng-model="names[$index]"... मुझे पता है कि यह एक वर्कअराउंड है, लेकिन यह काम करता है ;-)
ड्रेको कोको जूल


2

यह समस्या उस तरीके से प्रतीत होती है कि वह किस तरह से ng-modelकार्य करता है inputऔर nameवस्तु को अधिलेखित करता है, जिससे यह खो जाता है ng-repeat

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

<div ng-repeat="name in names">
    Value: {{name}}
    <input ng-model="names[$index]">                         
</div>

आशा करता हूँ की ये काम करेगा


1

मैंने अपनी समस्या के लिए ऊपर दिए गए समाधान की कोशिश की, यह एक आकर्षण की तरह काम करता है। धन्यवाद!

http://jsfiddle.net/leighboone/wn9Ym/7/

यहाँ मेरा संस्करण है कि:

var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
    $scope.models = [{
        name: 'Device1',
        checked: true
    }, {
        name: 'Device1',
        checked: true
    }, {
        name: 'Device1',
        checked: true
    }];

}

और मेरा HTML

<div ng-app="myApp">
    <div ng-controller="MyCtrl">
         <h1>Fun with Fields and ngModel</h1>
        <p>names: {{models}}</p>
        <table class="table table-striped">
            <thead>
                <tr>
                    <th></th>
                    <th>Feature 1</td>
                    <th>Feature 2</th>
                    <th>Feature 3</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>Device</td>
                   <td ng-repeat="modelCheck in models" class=""> <span>
                                    {{modelCheck.checked}}
                                </span>

                    </td>
                </tr>
                <tr>
                    <td>
                        <label class="control-label">Which devices?</label>
                    </td>
                    <td ng-repeat="model in models">{{model.name}}
                        <input type="checkbox" class="checkbox inline" ng-model="model.checked" />
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

-5

कुछ ऐसा कैसे करें:

<select ng-model="myModel($index+1)">

और मेरे निरीक्षक तत्व में:

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