डिफ़ॉल्ट मानों से कोणीय जेएस इनिट एनजी-मॉडल


126

मान लें कि आपके पास एक फ़ॉर्म है जिसमें डेटाबेस से लोड किए गए मान हैं। आप एनजी-मॉडल को कैसे शुरू करते हैं?

उदाहरण:

<input name="card[description]" ng-model="card.description" value="Visa-4242">

मेरे नियंत्रक में, शुरू में $ गुंजाइश.कार्ड अपरिभाषित है। क्या ऐसा कुछ करने के अलावा भी कोई रास्ता है?

$scope.card = {
  description: $('myinput').val()
}

जवाबों:


136

नए कोणीय अनुप्रयोगों में यह एक सामान्य गलती है। यदि आप इससे बच सकते हैं तो आप सर्वर पर अपने मूल्यों को अपने HTML में नहीं लिखना चाहते हैं। यदि वास्तव में, यदि आप अपने सर्वर को पूरी तरह से HTML सौंपने से दूर हो सकते हैं, तो सभी बेहतर।

आदर्श रूप से, आप अपने कोणीय HTML टेम्प्लेट को बाहर भेजना चाहते हैं, फिर JSON में $ http के माध्यम से अपने मूल्यों को नीचे खींचें और उन्हें अपने दायरे में रखें।

इसलिए यदि संभव हो तो ऐसा करें:

app.controller('MyController', function($scope, $http) {
    $http.get('/getCardInfo.php', function(data) {
       $scope.card = data;
    });
});

<input type="text" ng-model="card.description" />

यदि आप अपने सर्वर से अपने HTML में अपने मूल्यों को पूरी तरह से प्रस्तुत करते हैं, तो आप उन्हें एक वैश्विक चर में डाल सकते हैं और उन्हें $ विंडो के साथ एक्सेस कर सकते हैं:

अपने पृष्ठ के शीर्ष लेख में आप लिखेंगे:

<head>
   <script>
       window.card = { description: 'foo' };
   </script>
</head>

और फिर अपने कंट्रोलर में आपको ऐसा मिलेगा:

app.controller('MyController', function($scope, $window) {
   $scope.card = $window.card;
});

मुझे आशा है कि वह मदद करेंगे।


4
हाँ, यह मदद करता है। मुझे लगता है कि मैं हैरान हूँ कि कोणीय लोगों ने यह निर्णय लिया।
केल्विन फ्रेजेड

125
चौंकिए मत ... HTML का प्रतिपादन सर्वरों और ब्राउज़र से हट रहा है। इन दिनों जावास्क्रिप्ट में दर्जनों MVC फ्रेमवर्क मौजूद हैं, और यह JSON / XML डेटा को जावास्क्रिप्ट एप्स को होस्ट करने के लिए सर्वर की तुलना में कहीं अधिक कुशल है, जितना कि सर्वर पर हर एक पेज को प्रस्तुत करना है। यह सर्वर के हिट होने के बजाय क्लाइंट की मशीन को बहुत काम देता है। यह उल्लेख नहीं करने के लिए बैंडविड्थ पर बचाता है। यह सब बंद करने के लिए, आपके पास एक देशी मोबाइल ऐप (या वास्तव में कुछ भी) हो सकता है जो HTTP पर एक ही JSON का उपभोग करता है। यह भविष्य है।
बेन लेश

3
@ पत्थर: महान जवाब। बहुत बहुत धन्यवाद। मैं सहमत हूं कि यह आगे का रास्ता है और मैंने स्वयं इस दृष्टिकोण को अपनाना शुरू कर दिया है; क्या आपके पास कोई लिंक है जो इस दावे का समर्थन करता है? मैं बस इस बात से भी चिंतित हूं कि सर्वर से क्लाइंट तक html के रेंडरिंग को धीमा करने का परिणाम पेज लोड समय में हो सकता है, विशेष रूप से मोबाइल उपकरणों में जहां आप नेविगेशन ट्री के लिए बहुत सारे HTML जैसे रेंडर कर सकते हैं।
GFoley83

19
मैं असहमत हूं कि यह एक 'गलती' है। कुछ मामलों में, क्लाइंट-साइड रेंडरिंग सबसे अच्छा समाधान है। दूसरों में, सर्वर-साइड प्रतिपादन जाने का रास्ता है। आप दोनों तकनीकों के साथ कोणीय का उपयोग कर सकते हैं, और क्लाइंट-साइड रेंडरिंग को "कोणीय तरीके" के रूप में नहीं रखा जाना चाहिए, क्योंकि यह नहीं है। कोणीय इससे अधिक लचीला है।
शिकारी जूल

8
@ पत्थर, निश्चित रूप से - कोई भी उदाहरण जहां एसईओ महत्वपूर्ण है, लेकिन क्रॉलर्स के लिए वैकल्पिक सामग्री की लागत एम्बेडेड डेटा के साथ कोणीय को लागू करने की लागत से अधिक है - कोई भी एप्लिकेशन जो कथित गति या समय-दर-रेंडर के लिए बहुत अधिक मूल्य रखता है। उपयोगकर्ता अनुभव - कई सामग्री साइटें और ईकॉमर्स साइटें इनमें से एक श्रेणी में आती हैं। ट्विटर पर इंजीनियर, जिन्होंने क्लाइंट रेंडरिंग की कोशिश की, फिर एक बेहतर उपयोगकर्ता अनुभव देने के लिए सर्वर पर वापस चले गए, उन्होंने अपने तर्क को भी रेखांकित किया: blog.twitter.com/2012/improving-performance-twittercom
hunterloft.com

236

यदि आप अपने ऐप को ऐसा करने के लिए पुन: प्रयास नहीं कर सकते हैं, जो @blesh सुझाव देता है (JSON डेटा को $ http या $ संसाधन के साथ नीचे खींचें और $ स्कोप को आबाद करें), तो आप इसके बजाय ng-init का उपयोग कर सकते हैं :

<input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">

AngularJS भी देखें - इनपुट पाठ बॉक्स पर मूल्य विशेषता को नजरअंदाज कर दिया जाता है, जब एनजी-मॉडल का उपयोग किया जाता है?


कोणीय तरीके के लिए +1 (कम पसंदीदा अभ्यास का)। उदाहरण: jsfiddle.net/9ymB3
जॉन लेहमैन

2
मैं C # वेब रूपों के साथ कोणीय का उपयोग कर रहा हूं और मुझे लगता है कि ng-initकोड-पीछे / पोस्टबैक जैसे मान सेट करते समय उपयोग करना काफी उपयोगी है <input name="phone" data-ng-model="frm.phone" data-ng-init="frm.phone= '<%: Model.Phone %>'" data-ng-pattern="/^[0-9() \-+]+$/" type="tel" required />। थोड़ा बदसूरत? हाँ, लेकिन इस प्रक्रिया में चाल और एक एकीकरण सिरदर्द हल करता है।
GFoley83

13
+1, सुरुचिपूर्ण! लोग तड़क-भड़क और तेज़ व्यवहार की वकालत करते हैं, फिर भी यहाँ बहुत सारे एसओ कहते हैं, "क्या यह सभी ग्राहक पक्ष हैं", जैसे लाखों http कॉल तड़क-भड़क वाली साइटों के लिए अच्छा है। डेटा सर्वर साइड को टेम्प्लेट में सीडिंग करना रणनीतियों को कैशिंग करने में सक्षम बनाता है। मेमैक्टेड के साथ स्थिर, या गतिशील / आंशिक। यही ट्विटर करता है। कभी-कभी यह उपयोगी है, अन्य बार नहीं। तनाव देना चाहता था। बस यह जोड़ना था, ऐसा नहीं कि आपने अन्यथा कहा, @ मर्क।
oma

1
वास्तव में मैं इसे वापस लेता हूं, यह मेरे लिए सबसे अच्छा काम करता है, भयानक: stackoverflow.com/a/20522955/329367
डैरेन

1
एफडब्ल्यूआईडब्ल्यू: मैं टेम्प्लेट अभिव्यक्तियों में चर असाइनमेंट को नापसंद करता हूं क्योंकि यह परीक्षण योग्य नहीं है।
बेन लेश

60

यह स्पष्ट रूप से कमी है, लेकिन आसानी से जोड़ा गया AngularJS। इनपुट क्षेत्र से मॉडल मान सेट करने के लिए बस एक त्वरित निर्देश लिखें।

<input name="card[description]" value="Visa-4242" ng-model="card.description" ng-initial>

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

var app = angular.module('forms', []);

app.directive('ngInitial', function() {
  return {
    restrict: 'A',
    controller: [
      '$scope', '$element', '$attrs', '$parse', function($scope, $element, $attrs, $parse) {
        var getter, setter, val;
        val = $attrs.ngInitial || $attrs.value;
        getter = $parse($attrs.ngModel);
        setter = getter.assign;
        setter($scope, val);
      }
    ]
  };
});

अच्छा त्वरित निर्देशन। किसी भी अच्छे कारण से इसे एनजी-मॉडल में पैकेज नहीं किया जा सकता है ताकि मूल्य = और एनजी-मॉडल = एक साथ काम कर सकें क्योंकि अधिकांश लोग उम्मीद करेंगे?
शिकारी जूल

बहुत अच्छा! यह उपयोगी है।
सन्तिगोबसुल्तो

3
बहुत बढ़िया जवाब! मैंने सिर्फ एक "फिक्स" जोड़ दिया है ताकि यह textareas के साथ भी काम कर सके
रायन मॉन्टगोमेरी

आपने controllerअपने निर्देश के लिए परिभाषित क्यों किया, और linkविधि का उपयोग क्यों नहीं किया ?। मैं नौसिखिया हूँ angularjs करने के लिए
ebram khalil 15'14

1
val = $attrs.ngInitial || $attrs.value || $element.val()चुनिंदा तत्वों के साथ काम करने के लिए इसे बदलने की आवश्यकता है ।
fjsj

12

IMHO सबसे अच्छा समाधान @ केविन स्टोन निर्देश है, लेकिन मुझे इसे हर हालत में काम करने के लिए अपग्रेड करना था (फे चयन, टेक्सारिया), और यह एक निश्चित रूप से काम कर रहा है:

    angular.module('app').directive('ngInitial', function($parse) {
        return {
            restrict: "A",
            compile: function($element, $attrs) {
                var initialValue = $attrs.value || $element.val();
                return {
                    pre: function($scope, $element, $attrs) {
                        $parse($attrs.ngModel).assign($scope, initialValue);
                    }
                }
            }
        }
    });

और चयन के बारे में क्या?
जुवे

7

आप एक कस्टम निर्देश (textarea, चयन, रेडियो और चेकबॉक्स के समर्थन के साथ) का उपयोग कर सकते हैं, इस ब्लॉग पोस्ट की जाँच करें https://glaucocustodio.github.io/2014/10/20/init-ng-model-from-form-form फ़ील्ड-विशेषताएँ /


1
यह एक महान पोस्ट है। प्रश्न के बाद से मेरा पसंदीदा उत्तर प्रारंभिक मूल्यों के अनुसार एक इनपुट का मूल्य निर्धारित करना था।
RPDeshaies

मैंने इस कोड का परीक्षण करने के लिए एक Plnkr बनाया और यह बहुत अच्छा काम करता है: plnkr.co/edit/ZTFOAc2ZGIZr6HjsB5gH?p=preview
RPDeshaies

6

आप अपने HTML कोड के भीतर भी उपयोग कर सकते हैं: ng-init="card.description = 12345"

यह कोणीय द्वारा अनुशंसित नहीं है, और जैसा कि ऊपर उल्लेख किया गया है आपको विशेष रूप से अपने नियंत्रक का उपयोग करना चाहिए।

लेकिन यह काम करता है :)


4

मेरे पास एक सरल दृष्टिकोण है, क्योंकि मेरे रूपों में कुछ भारी मान्यताएं और मुखौटे हैं। इसलिए, मैंने अपने मूल्य को फिर से प्राप्त करने के लिए jquery का उपयोग किया और मान्यताओं के लिए "परिवर्तन" को आग लगा दी:

$('#myidelement').val('123');
$('#myidelement').trigger( "change");

3

जैसा कि अन्य ने बताया, विचारों पर डेटा को इनिशियलाइज़ करना अच्छा नहीं है। हालांकि, नियंत्रकों के डेटा की प्रारंभिक सिफारिश की जाती है। (देखें http://docs.angularjs.org/guide/controller )

तो आप लिख सकते हैं

<input name="card[description]" ng-model="card.description">

तथा

$scope.card = { description: 'Visa-4242' };

$http.get('/getCardInfo.php', function(data) {
   $scope.card = data;
});

इस तरह विचारों में डेटा शामिल नहीं है, और नियंत्रक मूल्य को इनिशियलाइज़ करता है जबकि वास्तविक मान लोड किए जा रहे हैं।


3

अगर आपको केविन स्टोन का दृष्टिकोण https://stackoverflow.com/a/17823590/584761 से ऊपर है, तो 'इनपुट' जैसे विशिष्ट टैग के लिए निर्देश लिखकर एक आसान दृष्टिकोण पर विचार करें

app.directive('input', function ($parse) {
    return {
        restrict: 'E',
        require: '?ngModel',
        link: function (scope, element, attrs) {
            if (attrs.ngModel) {
                val = attrs.value || element.text();
                $parse(attrs.ngModel).assign(scope, val);
            }
        }
    }; });

यदि आप इस मार्ग पर जाते हैं तो आपको हर टैग के लिए एनजी-प्रारंभिक जोड़ने की चिंता नहीं करनी होगी। यह स्वचालित रूप से टैग के मूल्य विशेषता के लिए मॉडल के मूल्य को निर्धारित करता है। यदि आप मान विशेषता सेट नहीं करते हैं, तो यह एक रिक्त स्ट्रिंग के लिए डिफ़ॉल्ट होगा।


3

यहाँ एक सर्वर केंद्रित दृष्टिकोण है:

<html ng-app="project">
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <script>
        // Create your module
        var dependencies = [];
        var app = angular.module('project', dependencies);

        // Create a 'defaults' service
        app.value("defaults", /* your server-side JSON here */);

        // Create a controller that uses the service
        app.controller('PageController', function(defaults, $scope) {
            // Populate your model with the service
            $scope.card = defaults;
        });
    </script>

    <body>
        <div ng-controller="PageController">
            <!-- Bind with the standard ng-model approach -->
            <input type="text" ng-model="card.description">
        </div>
    </body>
</html>

यह $ प्रदान के अलावा इस सवाल पर अधिक लोकप्रिय जवाब के रूप में एक ही मूल विचार है ऐसी सेवा को पंजीकृत करता है जिसमें आपके डिफ़ॉल्ट मान शामिल होते हैं।

इसलिए, सर्वर पर, आप कुछ इस तरह से हो सकते हैं:

{
    description: "Visa-4242"
}

और इसे अपनी पसंद के सर्वर-साइड तकनीक के माध्यम से अपने पेज में डालें। यहाँ एक Gist है: https://gist.github.com/exclsr/c8c391d16319b2b313143


1
जहां तक ​​मैं बता सकता हूं, यह समस्या को संभालने के लिए सबसे अधिक कोणीय तरीका है यदि प्रारंभिक $ http अनुरोध करना एक विकल्प नहीं है। यदि आप बाद में $ http को स्वैप करना चाहते हैं, तो इसे संशोधित करने में बहुत आसान होने का लाभ भी है। एक संभव वृद्धि यह है कि बदलाव को और भी आसान बनाने के बजाय एक वादा वापस करना। मैं वैश्विक संस्करण स्थापित करने या यहां एनजी-प्रारंभिक का उपयोग करने से बहुत शर्म करूंगा।
richard

1

यह ऊपर वर्णित विचारों का एक अधिक सामान्य संस्करण है ... यह केवल यह जांचता है कि क्या मॉडल में कोई मूल्य है, और यदि नहीं, तो यह मूल्य को मॉडल पर सेट करता है।

जे एस:

function defaultValueDirective() {
    return {
        restrict: 'A',
        controller: [
            '$scope', '$attrs', '$parse',
            function ($scope, $attrs, $parse) {
                var getter = $parse($attrs.ngModel);
                var setter = getter.assign;
                var value = getter();
                if (value === undefined || value === null) {
                    var defaultValueGetter = $parse($attrs.defaultValue);
                    setter($scope, defaultValueGetter());
                }
            }
        ]
    }
}

HTML (उपयोग उदाहरण):

<select class="form-control"
        ng-options="v for (i, v) in compressionMethods"
        ng-model="action.parameters.Method"
        default-value="'LZMA2'"></select>

यह मेरे लिए काम किया है, लेकिन केवल $scopeकॉल करने के लिए पारित करने के बाद getter()- उम्मीद है कि यह किसी और के लिए चीजों को साफ करने की कोशिश कर रहा है!
zesda

0

मैंने कोशिश की कि @ मर्क राजकोक ने क्या सुझाव दिया। स्ट्रिंग मानों के लिए इसका काम कर रहा है (वीजा -4242)। कृपया इस फील को देखें

फिडेल से:

फिडेल में वही काम किया जा सकता है ng-repeat, जिसका उपयोग हर कोई कर सकता है। लेकिन @ मर्को राजकोक द्वारा दिए गए उत्तर को पढ़ने के बाद, मैं सिर्फ प्रोफाइल की सरणी के साथ फॉर्म के लिए कोशिश करना चाहता था। चीजें अच्छी तरह से काम करती हैं मेरे पास $ गुंजाइश है। लाभ = = {{}, {}]; नियंत्रक में कोड। यदि मैं इस कोड को हटाता हूं, तो त्रुटियां हो रही हैं। लेकिन सामान्य स्थितियों में मैं $scope.profiles = [{},{}]; सर्वर से HTML प्रिंट या इको प्रिंट नहीं कर सकता। क्या उपरोक्त प्रकार से निष्पादित करना संभव होगा, जैसा @Mark Rajcok ने स्ट्रिंग मानों के लिए किया था <input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">, जैसे कि सर्वर से जावास्क्रिप्ट भाग को प्रतिध्वनित किए बिना।


1
आप सरणी को इनिशियलाइज़ करने के लिए एनजी-इनिट का उपयोग कर सकते हैं और फिर फॉर्म लाइनों को आउटपुट करने के लिए एनजी-रिपीट का उपयोग कर सकते हैं: jsfiddle.net/6tP6x/1
करेन जिल्स

0

रेयान मोंटगोमरी "फिक्स" के लिए चयनित तत्व के लिए बस समर्थन जोड़ा गया

<select class="input-control" ng-model="regCompModel.numberOfEmployeeId" ng-initial>
    <option value="1af38656-a752-4a98-a827-004a0767a52d"> More than 500</option>
    <option value="233a2783-db42-4fdb-b191-0f97d2d9fd43"> Between 250 and 500</option>
    <option value="2bab0669-550c-4555-ae9f-1fdafdb872e5"> Between 100 and 250</option>
    <option value="d471e43b-196c-46e0-9b32-21e24e5469b4"> Between 50 and 100</option>
    <option value="ccdad63f-69be-449f-8b2c-25f844dd19c1"> Between 20 and 50</option>
    <option value="e00637a2-e3e8-4883-9e11-94e58af6e4b7" selected> Less then 20</option>
</select>

app.directive('ngInitial', function () {
return {
    restrict: 'A',
    controller: ['$scope', '$element', '$attrs', '$parse', function ($scope, $element, $attrs, $parse) {
        val = $attrs.sbInitial || $attrs.value || $element.val() || $element.text()
        getter = $parse($attrs.ngModel)
        setter = getter.assign
        setter($scope, val)
    }]
}

});


0

यदि आपके पास URL में इनिट वैल्यू है mypage/id, तो कोणीय JS के कंट्रोलर में आप location.pathnameआईडी ढूंढने के लिए उपयोग कर सकते हैं और इसे अपने इच्छित मॉडल को असाइन कर सकते हैं।

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