2012-08-01 9 views
19

अगर मैं इसे ठीक से नहीं कह रहा हूं तो मैं पहले से माफ़ी मांगता हूं। मेरे पास ng-model के साथ ng-repeat के अंदर एक टेक्स्टबॉक्स है और जब मैं टेक्स्टबॉक्स मान प्राप्त करने का प्रयास करता हूं तो यह हमेशा undefined होता है। मैं चाहता हूं कि मैं जो कुछ भी संबंधित टेक्स्टबॉक्स में टाइप करूं उसे प्रदर्शित करना चाहता हूं।

यह $scope के साथ एक समस्या प्रतीत होता है, तो मैं $scope.postText वैश्विक या नियंत्रक रूट स्तर पर कैसे बना सकता हूं ताकि यह पहुंच योग्य हो सके? http://jsfiddle.net/stevenng/9mx9B/14/

उत्तर

25

आपके क्लिक अभिव्यक्ति में आप अपने savePost समारोह में postText और उपयोग यह देख सकते हैं:

यहाँ तक स्पष्ट बातें मदद करने के लिए JSFiddle है। यदि यह एनजी-दोहराना में नहीं था तो आप एकल $scope.postText सफलतापूर्वक एक्सेस कर सकते थे लेकिन ng-repeat प्रत्येक आइटम के लिए एक नया दायरा बनाता है।

Here एक अद्यतन पहेली है।

<div ng-repeat="post in posts"> 
    <strong>{{post}}</strong> 
    <input type="text" ng-model="postText"> 
    <a href="#" ng-click="savePost(postText)">save post</a> 
</div> 

$scope.savePost = function(post){ 
    alert('post stuff in textbox: ' + post); 
} 
+0

कैसे आप इस मिलेगा काम करने के लिए मूर्ख? http://jsfiddle.net/stevenng/VnQqH/5/ – Steve

+9

http://jsfiddle.net/VnQqH/6/ वास्तविक वर्तमान दायरे को संदर्भित करने के लिए 'this' का उपयोग करें –

+0

धन्यवाद रेनान जो बहुत मदद करता है। मुझे यह 'save post' जैसी 2 वस्तुओं में गुजरकर काम कर रहा है। लेकिन एक सरल 'यह' का उपयोग करना बहुत बेहतर है! – Steve

45

@Gloopy जैसा कि पहले ही कहा गया है, एनजी-दोहराने अपने posts सरणी में प्रत्येक आइटम के लिए एक नए बच्चे गुंजाइश पैदा करता है। चूंकि posts सरणी का प्रत्येक आइटम एक आदिम (एक स्ट्रिंग) है, ng-repeat प्रत्येक बच्चे के दायरे पर post प्रॉपर्टी भी बनाता है, और उनमें से प्रत्येक को सरणी से उपयुक्त मान निर्दिष्ट करता है। एनजी-दोहराना ब्लॉक के अंदर ng-model="postText" है। यह प्रत्येक बच्चे के scopes पर एक पोस्टटेक्स्ट संपत्ति बनाता है। यहाँ सब (4 बच्चे स्कोप के 2 के लिए) कैसा दिखता है जो:

ng-repeat scopes

कोई उपयोगकर्ता इनपुट बक्सें में से एक में कुछ पाठ, उचित ग्रे बॉक्स पाठ की दुकान जाएगा। (उदा।, दूसरा (शीर्ष से) ग्रे बॉक्स टेक्स्ट को उपयोगकर्ता प्रकार को "तकनीक" टेक्स्टबॉक्स में संग्रहीत करेगा।) मूल दायरे बच्चे के दायरे में पोस्टटेक्स्ट गुण नहीं देख सकता - यह आपकी समस्या है।

  1. @ gloopy का जवाब: (क्योंकि एनजी-दोहराने बच्चे स्कोप prototypically माता पिता दायरे से विरासत जो बच्चे स्कोप उपयोग कर सकते हैं) माता-पिता गुंजाइश पर एक समारोह को परिभाषित करने और बच्चे गुंजाइश संपत्ति पारित वहाँ तीन आम समाधान कर रहे हैं मूल्य (यानी, पोस्टटेक्स्ट का मान) माता-पिता तक।
  2. अपने posts सरणी में प्राइमेटिव के बजाय ऑब्जेक्ट्स का उपयोग करें। उदाहरण के लिए,
    $scope.posts = [ {type: 'tech'}, {type: 'news'}, ...]; अपने एनजी-दोहराने पाश में
    फिर, का उपयोग
    <input type="text" ng-model="post.postText">
    क्योंकि प्रत्येक सरणी आइटम एक वस्तु है (और एक आदिम नहीं), प्रत्येक बच्चे गुंजाइश, सरणी posts में उपयुक्त वस्तु के लिए एक संदर्भ हो जाता है के बजाय एक प्रति (एक मूल्य का)। इसलिए, post.postText मूल $ स्कोप संपत्ति posts पर बनाया गया है, और इसलिए यह मूल दायरे के लिए दृश्यमान है। (इसलिए, इस मामले में बच्चे के स्कोप बस savePost() पर कॉल करेंगे - माता-पिता के दायरे तक किसी भी मूल्य को पास करने की आवश्यकता नहीं होगी।)
    दूसरे शब्दों में, यदि उपयोगकर्ता ने "यह तकनीक संबंधित है" पहले टाइप किया है टेक्स्ट बॉक्स, माता-पिता में posts सरणी स्वचालित रूप से निम्नानुसार अपडेट की जाएगी:
    $scope.posts = [ {type: 'tech', postText: 'this is tech related'}, {type: 'news'}, ...];
    एक आखिरी नोट: पोस्टटेक्स्ट प्रॉपर्टी पोस्ट ऑब्जेक्ट में तब तक नहीं जोड़ा जाता जब तक कि उपयोगकर्ता कुछ टाइप न करे।
  3. बच्चे के दायरे के बजाए, माता-पिता के दायरे पर किसी संपत्ति के लिए फॉर्म तत्व को बाध्य करने के लिए ng-model="$parent.someProperty" का उपयोग करें।यह समाधान आपके परिदृश्य के लिए कार्यान्वित करना मुश्किल होगा, और यह एक नाजुक समाधान है, क्योंकि यह स्कोप विरासत के लिए HTML संरचना पर निर्भर करता है ... लेकिन मैं इसे पूर्णता के लिए उल्लेख करता हूं। ।

(एक चौथाई समाधान @ gloopy के जवाब पर टिप्पणी में @Renan द्वारा प्रस्तुत किया गया था यह एक तरह समाधान 1. है, लेकिन एक बदलाव के साथ: this माता-पिता के लिए ऊपर एक मूल्य गुजर के बजाय प्रयोग किया जाता है मैं। मैं इस दृष्टिकोण के प्रशंसक नहीं हूं क्योंकि यह निर्धारित करना मुश्किल बनाता है कि कौन से $ स्कोप का उपयोग किया जा रहा है या संशोधित किया जा रहा है। मुझे लगता है कि यह बेहतर है कि $ स्कोप पर परिभाषित कार्य केवल अपने स्वयं के $ स्कोप को एक्सेस और संशोधित करते हैं।)

और अधिक के लिए एंगुलर में प्रोटोटाइप स्कोप विरासत कैसे काम करता है, इस बारे में जानकारी (और बहुत अधिक तस्वीरें), What are the nuances of scope prototypal/prototypical inheritance in AngularJS?

+0

मैं नहीं देख रहा हूं कि 2 में आप savePost() को कुछ भी पास किए बिना कॉल कर सकते हैं। बच्चे ऑब्जेक्ट या इंडेक्स को पास किए बिना आप एक विशिष्ट बच्चे के दायरे को कैसे देखेंगे? –

+0

@ डीन, अच्छा बिंदु। आप 'पोस्ट' के माध्यम से लूप कर सकते हैं और यह निर्धारित कर सकते हैं कि कौन सा (ओं) बदल गया है (उदा।, अगर आप केवल एक "सेव करें" बटन चाहते थे)। या यदि आप प्रत्येक पोस्ट के लिए "पोस्ट सहेजें" लिंक चाहते हैं, तो आप 'post.type' को तर्क के रूप में पास कर सकते हैं। –

+0

यदि आप अभिभावकस्कोप के बारे में भाग को चित्रित करते हैं तो बॉक्स में टाइप किए गए पाठ को देखने में सक्षम नहीं होने पर चित्र बेहतर हो सकता है। यह दिखाने के लिए एक लाल रेखा या कुछ अन्य तरीका बनाएं कि बॉक्स में दर्ज चीजें माता-पिता को दिखाई नहीं दे रही हैं। –

2

यह देर से उत्तर दे सकता है। कृपया इस पहेली को देखें। http://jsfiddle.net/X5gd2/ कृपया फ़ायरबग के कंसोल का संदर्भ लें, जब आप टेक्स्ट बॉक्स में कुछ ग्रंथ टाइप करने के बाद लिंक पर क्लिक करते हैं। विचार है कि एनजी-दोहराना के अंदर दोहराए गए प्रत्येक दृश्य के लिए एक आइटम नियंत्रक होना है।

आइटम नियंत्रक:

function postItemController($scope){ 
    $scope.savePost = function(){ 
     console.log($scope.postText + " which belongs to " + $scope.post +" will be saved") 
    } 
} 
1

स्प्लिट शीर्षक और

angular.module('MyApp',[]); 

function PostCtrl($scope) { 
    $scope.posts = [{heading:'tech',value:''}, {heading:'news',value:''},  {heading:'sports',value:''},{heading:'health',value:''}]; 

    $scope.savePost = function(post){ 
     alert('post stuff in textbox: ' + post); 
    } 
} 

एचटीएमएल नीचे मूल्य में मॉडल ..

<div ng-app="MyApp"> 
    <div ng-controller="PostCtrl"> 
     <div ng-repeat="post in posts"> 
      <strong>{{post.heading}}</strong> 
      <input type="text" ng-model="post.value"> 
      <a href="#" ng-click="savePost(post.value)">save post</a> 
     </div> 
    </div> 
</div> 

Check out this Fiddle..