2014-05-15 7 views
25

निम्न कोड त्रुटि को फेंकता है "TypeError: जब मैं" चेक "बटन पर क्लिक करता हूं तो" अविश्वसनीय "संपत्ति '$ pristine' नहीं पढ़ सकता।

app.controller('MainCtrl', function($scope) { 
    // other stuff 
}) 

.controller('Ctrl2', function($scope) { 
    $scope.product = {description:'pump'}; 
    $scope.output = 'unknown'; 
    // uncomment to avoid undefined error, still can't see $pristine 
    // $scope.formHolder = {}; 
    $scope.checkForm = function() { 
    $scope.descriptionTest = $scope.product.description; 
    if ($scope.formHolder.productForm.$pristine) { 
     $scope.output = 'yes'; 
    } 
    if ($scope.formHolder.productForm.$dirty) { 
     $scope.output = 'no' 
    } 
    } 
}); 

एचटीएमएल

<body ng-controller="MainCtrl"> 
    <div > 
     <ng-include ng-controller="Ctrl2" src="'myForm.html'"></ng-include> 
    </div> 
    </body> 

myForm.html

<form name="productForm" novalidate> 
    <h2>myForm</h2> 
    description: <input type="text" name="description" ng-model="product.description"/> 
    <br> 
    <button ng-click="checkForm()">Check Form</button> 
    <br> 
    Form Pristine: {{output}} 
    <br><br> 
    I can see the description: {{descriptionTest}} 
</form> 

plunkr

समस्या यह है कि मेरी Ctrl2 productForm नहीं देख सकता है। पहले तो मुझे लगा कि यह प्रोटोटाइप विरासत के साथ करना था कि एनजी-शामिल नहीं है जब यह एक बच्चे के दायरे में आता है, तो मैं Ctrl2 में एक चर जोड़ने की कोशिश की:

$scope.productForm = {}; 

यह त्रुटि से छुटकारा मिला, लेकिन मेरी नियंत्रक अभी भी $ pristine या $ गंदे सही ढंग से नहीं देख रहा था।

मैं अंत में यह productForm ऊपर एक $ scope.formHolder वस्तु जोड़कर काम कर गया:

plunkr

.controller('Ctrl2', function($scope) { 
    $scope.product = {description:'pump'}; 
    $scope.output = 'unknown'; 
    // uncomment to avoid undefined error, still can't see $pristine 
    $scope.formHolder = {}; 
    $scope.checkForm = function() { 
    $scope.descriptionTest = $scope.product.description; 
    if ($scope.formHolder.productForm.$pristine) { 
     $scope.output = 'yes'; 
    } 
    if ($scope.formHolder.productForm.$dirty) { 
     $scope.output = 'no' 
    } 
    } 
}); 

एचटीएमएल

<form name="formHolder.productForm" novalidate> 

क्यों काम करता है? और क्या ऐसा करने का एक बेहतर तरीका है?

मैं इस तरह से समाप्त हुआ क्योंकि मेरे पास एक काम करने वाला फॉर्म & नियंत्रक/टेम्पलेट था जिसे मैं कहीं और पुन: उपयोग करना चाहता था। मुझे शायद निर्देश बनाना चाहिए, लेकिन सबकुछ ठीक से काम करता है और फॉर्म के $ गंदे फीचर्स को छोड़कर - सभी एनजी-मॉडल वर्र्स सही ढंग से पारित किए गए थे।

How can I set a form contained inside a ng-include to be prestine? का उत्तर है कि "सभी नियम तोड़ते हैं" लेकिन अधिक जटिल लग रहा था।

जब मैं लिखता हूं कि फॉर्म नियंत्रक कब दायरे में $ pristine जोड़ता है, और किस दायरे में?

संपादित करें/उत्तर:

मेरे मूल सवाल यह है कि प्रपत्र निर्देश गुंजाइश के लिए लिखते हैं के बारे में भ्रम की स्थिति के लिए नीचे उबला हुआ जा सकता है।

$scope.productForm = formObject; 

तो: मैं धारणा है कि यह

<form name="productForm">... 

में बात लेने के लिए और यह करने के लिए गुण जोड़ना होगा,

$scope.productForm.$pristine = function() {...} 

तथापि की तरह था, यह productForm के शीर्ष पर सीधे लिखते हैं , फॉर्म ऑब्जेक्ट को बच्चे में संग्रहीत किया जाता है और माता-पिता को चयनित उत्तर में समझाया नहीं जाता है।

बच्चे की गुंजाइश विरासत में महत्वपूर्ण गड़बड़ी जिसने मेरी मदद की है कि श्रृंखला को पढ़ने में परामर्श दिया जाता है, लेकिन लिखना नहीं है। तो अगर आप बच्चे की तरह कुछ सेट करते हैं। MyThing।संपत्ति = '123', जबकि यह एक लिखने जैसा दिखता है, इसे पहले यह पता लगाने के लिए पढ़ना पड़ता है कि मेरा टिंग क्या है। जबकि childScope.myThing = '567' को सेट करना प्रत्यक्ष लेखन है, और इसमें मूल श्रृंखला को बिल्कुल शामिल नहीं करना शामिल है। यह सब बेहतर ढंग से समझाया गया है: What are the nuances of scope prototypal/prototypical inheritance in AngularJS?

उत्तर

14

यह समझने के लिए कि formHolder के साथ समाधान क्यों आपको JavaScript prototypes chain को समझना होगा। के निम्नलिखित छद्म कोड में formHolder बिना पहले मामले को वर्णन करते हैं:

$parentScope = { 
    //I'm a parent scope inside Ctrl2 
    productForm:{} //to avoid undefined reference error 
} 

$childScope = { 
    //I'm a child scope created by by ng-include 
    __protototype__: $parentScope 
} 

जब form निर्देश पार्स किया गया है यह FormController जो name विशेषता मान में संकेत कुंजी के अंतर्गत $scope संपत्ति पर सेट किया जाता है बनाता है।

$childScope.productForm = $formCtrl; 

इसके बाद 2 स्कोप इस तरह दिखेगा:

$parentScope = { 
    //I'm a parent scope inside Ctrl2 
    productForm:{} //to avoid undefined reference error 
} 

$childScope = { 
    //I'm a child scope created by by ng-include 
    productForm: $formCtrl 

    __protototype__: $parentScope 
} 

तो आप वास्तव में साथ 2 गुण समाप्त हो गया अलग-अलग दायरों पर विभिन्न वस्तुओं पकड़े यह काफी के बराबर है। जब form निर्देश $scope इस बार यह अलग संपत्ति श्रृंखला का उपयोग करता है पर FormController उदाहरण स्थापित कर रही है

$parentScope = { 
    //I'm a parent scope inside Ctrl2 
    formHolder:{} //to avoid undefined reference error 
} 

$childScope = { 
    //I'm a child scope created by by ng-include 
    __protototype__: $parentScope 
} 

: अब दूसरे मामले में आप निम्नलिखित स्थिति है

$childScope.formHolder.productForm = $formCtrl; 

कौन सा बराबर है लिखने के लिए:

var formHolder = $childScope.formHolder; //since formHolder isn't defined on $childScope 
//the JS runtime will look for it in the prototypes chain and find it inside $parentScope 
//so here formHolder is the very same object you created and set on $parentScope 
formHolder.productForm = $formCtrl; 

आशा यह समझने में मदद करता है कि दूसरा विकल्प क्यों काम करता है। आप के दूसरे भाग के रूप में सवाल - अपने समाधान सरल और पूरी तरह से व्यवहार्य है - लेकिन वहाँ अन्य तरीकों से इसे संभाल करने के लिए की जोड़ी जो सबसे अच्छा है कर रहे हैं वास्तविक उपयोग संदर्भ पर निर्भर करता:

  • बच्चे गुंजाइश बिना निर्देशों का उपयोग निकालने के लिए आम मार्कअप और बच्चे गुंजाइश है कि या तो प्रत्यक्ष माता पिता गुंजाइश संपत्ति का उपयोग के माध्यम से या उत्सर्जित घटनाओं
  • एक custom include directive का उपयोग कर उस बच्चे गुंजाइश नहीं बन जाएगा के माध्यम से राज्य परिवर्तनों के बारे में हैं के साथ निर्देशों का उपयोग कार्यक्षमता
  • के कुछ हिस्सों
+0

AngularJS में के लिए

<!—- The vars should live in the controller. I placed them here for the example. -—> <div ng-controller=“controllerName” ng-init="form={}; model={}" > <div ng-include=“ ‘path-to-the-template’ ”></div> </div> <!—- Inside path-to-the-template -—> <form name="form.createUser"> <input name="name" ng-model="model.name" /> <input name="email" ng-model="model.email" /> </form> 

लिंक यह माध्यम से डॉट अंकन कहते हैं। – Walfrat

0

मुझे पता है कि यह एक पुराना सवाल है, लेकिन मुझे एक ही समस्या थी, और मैंने एचटीएमएल बदल दिया और एचटीएमएल फाइल के भीतर अपना एनजी-नियंत्रक शामिल किया।

तो बजाय

<ng-include ng-controller="Ctrl2" src="'myForm.html'"></ng-include> 

बदलें यह भी

<ng-include="'myForm.html'"></ng-include> 

और फिर myForm.html फ़ाइल में, एक div में कोड लपेट, और एनजी नियंत्रक विशेषता जोड़ है, तो आपके MyForm।एचटीएमएल बन जाएगा

<div ng-controller="Ctrl2"> 
    <form name="productForm" novalidate> 
     <h2>myForm</h2> 
     description: <input type="text" name="description" ng-model="product.description"/> 
     <br> 
     <button ng-click="checkForm()">Check Form</button> 
     <br> 
     Form Pristine: {{output}} 
     <br><br> 
     I can see the description: {{descriptionTest}} 
    </form> 
</div> 

अब अपने बच्चे नियंत्रक एनजी-शामिल गुंजाइश

1

बस नियंत्रक में चर (खाली वस्तु) को परिभाषित करने और इसका इस्तेमाल अपने प्रपत्र को परिभाषित करते हुए भीतर है। चूंकि कोणीय जेएस हुड के नीचे स्कोप प्रोटोटाइप का उपयोग करता है, जब फॉर्म आंतरिक दायरे (चर को बूटस्ट्रैप करने के लिए) तक पहुंचने का प्रयास करेगा, तो यह पहले स्कोप चेन के माध्यम से जाएगा और माता-पिता के दायरे में एक ही चर को खोजने का प्रयास करेगा। संदर्भ http://blog.152.org/2014/07/angular-form-element-not-attaching-to.html

संबंधित मुद्दे