2013-01-25 9 views
19

मैं यह पता लगाने की कोशिश कर रहा हूं कि जब मेरा डेटा किसी सेवा में संग्रहीत होता है तो आप बाध्यकारी तरीके से कैसे संभालते हैं।AngularJS सेवाओं में डेटा बाध्यकारी संभाल

अगर यह $ स्कोप में सेवा डालता है और फिर टेम्पलेट्स को सीधे इसमें बांधने के लिए काम मिल सकता है लेकिन यह वास्तव में एक बुरा विचार लगता है।

मैं मूल रूप से ऐसा करना चाहता हूं ताकि मेरे विचार/नियंत्रक आसानी से राज्य में सेवा को बदल सकें और यह हर जगह परिलक्षित हो।

ऐसा लगता है कि मुझे निम्न की तरह कुछ करने में सक्षम होना चाहिए, लेकिन यह काम नहीं करता है (http://jsfiddle.net/aidankane/AtRVD/1/)।

एचटीएमएल

<div ng-controller="MyCtl"> 
    <select ng-model="drawing" ng-options="d.file for d in drawings"></select> 
</div> 
<div ng-controller="MyOtherCtl"> 
    {{ drawing }} 
</div> 

जे एस

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

myApp.factory('myService', function(){ 
    var me = { 
     drawings: [{'file':'a'}, {'file':'b'}] 
    }; 
    // selected drawing 
    me.drawing = me.drawings[0]; 
    return me; 
}); 

function MyCtl($scope, myService){ 
    // can do: 
    // $scope.mys = myService; 
    // and then in html ng-model="mys.drawing" 
    // but that seems wrong 

    $scope.drawings = myService.drawings; 
    $scope.drawing = myService.drawing; 

    // can I not do this? it doesn't seem to work anyway... 
    $scope.$watch('drawing', function(drawing){ 
     myService.drawing = drawing; 
    }); 
} 

function MyOtherCtl($scope, myService){ 
    $scope.drawing = myService.drawing; 
} 

MyCtl.$inject = ['$scope', 'myService']; 
MyOtherCtl.$inject = ['$scope', 'myService']; 
+0

मैं देखता हूं कि आप $ scope.d बदलने के लिए कहां देख रहे हैं, लेकिन आप मॉडल को बदल नहीं रहे हैं, चयनित आइटम बदल रहे हैं। क्या आपको चयनित आइटम परिवर्तन के लिए संभवतः निर्देश में एक हैंडलर नहीं रखना चाहिए? –

+0

मैं निर्देशों का उपयोग करके यह कैसे करूँगा? मैंने पाया कि ngSelect निर्देश मूल रूप से मुझे वह व्यवहार देता है जो मुझे चाहिए। इस मुद्दे की मेरी समझ यह है कि यह नियंत्रक और सेवा के बीच की गति है जो समस्या है - फिर फिर मैं थोड़ा उलझन में हूं :) –

+0

आप सही हैं, अब मैं आपके अपडेट किए गए पहेली को देखता हूं, मेरे पास एक बेहतर विचार है आप क्या कर रहे हैं आप उलझन में नहीं हैं :) –

उत्तर

41

आप $watch का उपयोग करने और पारित करने के एक समारोह सेवाओं से आबद्ध कर सकते हैं:

$scope.$watch(function() { return myService.drawing; }, function (drawing) { 
    // handle it here. e.g.: 
    $scope.drawing = drawing; 
}); 

और फिर अपने टेम्पलेट में $scope.drawing का उपयोग करें और वे स्वचालित रूप से होगा अद्यतन:

<div ng-controller="MyOtherCtl"> 
    {{ drawing }} 
</div> 
+1

ठीक है। मुझे सही रास्ते पर सेट किया गया है, मुझे लगता है। इसलिए, मैंने एक नया संस्करण बनाया है - http://jsfiddle.net/aidankane/EBr53/ - और मैंने सेवा के बीच धक्का/खींचने के लिए दोनों दिशाओं में वॉचर्स बनाए हैं। क्या यह करने का सही तरीका है? –

+0

@ एडनकेन हाँ! अंतर-घटक संचार यहां और मेलिंग सूची पर एक आम प्रश्न है। सेवाएं अब तक का सबसे आम (और आमतौर पर अधिक "सही") समाधान हैं। –

+0

मैंने बहुत जल्दी देखा कि वे डेटा रखने का सही तरीका हैं। बस सेवा/नियंत्रक/दृश्य के बीच समन्वय के साथ थोड़ा संघर्ष कर रहा है। ऐसा लगता है कि सेवा का उपयोग करके मुझे नियंत्रकों में चीजों को सिंक करने के लिए थोड़ा बॉयलरप्लेट डालना होगा (नियंत्रकों में बहुत कम है जो मुझे कोई फर्क नहीं पड़ता)। त्वरित प्रतिक्रियाओं के लिए धन्यवाद, सराहना की। –

2

मुझे लगता है कि वादे के साथ काम करने के लिए और भी सुरुचिपूर्ण है ($q.deferred() देखें) और उन्हें अतुल्यकालिक रूप से हल करने के लिए। वादे समारोह में आप डेटा को $scope के सदस्यों को असाइन कर सकते हैं।

+0

यह ठीक है अगर आप केवल एक बार अपना डेटा लोड करते हैं, लेकिन मुझे नहीं लगता कि जो डेटा बदल रहा है वह स्वचालित रूप से रास्ते में बाध्य होगा ओपी की तलाश है गलत हो सकता है –

2

सेवा से डेटा को बांधने के दो तरीके हैं: 1) मूल्य के अनुसार (सेवा प्राइमेटिव वैल्यू में परिवर्तनीय परिवर्तनों की जांच के लिए उपरोक्त किए गए वॉचर की आवश्यकता होगी) 2) संदर्भ के अनुसार (मूल्य सीधे जुड़े हुए हैं) जो डेटा बाध्यकारी की मेरी पसंदीदा विधि है।

मैं केवल दूसरी संभावना को समझाऊंगा क्योंकि स्वीकृत उत्तर पहले ही दिखाता है कि एक वॉचर कैसे कार्यान्वित किया जा सकता है। This blog describes what I am going to explain very well

एचटीएमएल

<!DOCTYPE html> 
<html ng-app="myApp"> 

    <head> 
    <script data-require="[email protected]" data-semver="1.5.0" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.js"></script> 
    <link rel="stylesheet" href="style.css" /> 
    <script src="script.js"></script> 
    </head> 

    <body ng-controller="myAppCntrl"> 
    <h1>Hello Plunker!</h1> 
    <h3>By value</h3> 
    <p>{{byValue}}</p> 
    <p>{{objByValue}}</p> 
    <h3>By object in service reference</h3> 
    <p>{{byRefence.stringPrimitive}}</p> 
    <h3>By reference to service singleton</h3> 
    <p>{{myservice.stringPrimitive}}</p> 
    <p style="color: green">of course, you can reference an object through the service as well</p> 
    <p>{{myservice.objectWithPrimitive.stringPrimitive}}</p> 

    <button ng-click=update()>Update strings on service</button> 
    <br /> 
    <button ng-click=setDefaults()>Restore Defaults</button> 
    </body> 

</html> 

JAVASCRIPT

var myApp = angular.module("myApp", []); 

myApp.controller('myAppCntrl', function($scope, myAppService){ 
    $scope.myservice = myAppService; 
    $scope.byValue = myAppService.stringPrimitive; 
    $scope.objByValue = myAppService.objectWithPrimitive.stringPrimitive; 
    $scope.byRefence = myAppService.objectWithPrimitive; 

    $scope.update = function() { 
    myAppService.stringPrimitive = "updated string"; 
    myAppService.objectWithPrimitive.stringPrimitive = "updated string here too"; 
    }; 
    $scope.setDefaults = function() { 
    myAppService.stringPrimitive = 'string primitive'; 
    myAppService.objectWithPrimitive.stringPrimitive = 'string primitive'; 
    }; 
}); 

myApp.service('myAppService', function(){ 
    this.stringPrimitive = 'string primitive'; 
    this.objectWithPrimitive = { 
    stringPrimitive: 'string primitive' 
    }; 
}); 

तो यह कैसे काम करता है:

I created this plunk to illustrate data binding by reference.

यहाँ खनखनाहट से कोड है?

यह समझना महत्वपूर्ण है कि कोणीय कार्यों के साथ इसका कोई संबंध नहीं है, और जावास्क्रिप्ट कैसे काम करता है इसके साथ बहुत कुछ करना है। जब एक चर को जावास्क्रिप्ट (पूर्णांक, स्ट्रिंग, आदि) में एक आदिम मान (या किसी फ़ंक्शन पर पास किया गया) के बराबर सेट किया जाता है var var द्वारा निर्धारित किया जाता है। इसका अर्थ यह है कि नया चर वैरिएबल की एक प्रति है जिसे आप स्मृति में किसी नए स्थान के बराबर सेट कर रहे हैं। जब एक चर को जावास्क्रिप्ट में किसी ऑब्जेक्ट (या किसी फ़ंक्शन पर पास किया गया) के बराबर सेट किया जाता है तो var संदर्भ द्वारा सेट किया जाता है।

इसका क्या अर्थ है?

जब एक $ स्कोप var मूल्य द्वारा सेट किया जाता है, और सेवा परिवर्तनीय परिवर्तन होता है, क्योंकि $ स्कोप वेरिएबल केवल सेवा चर की एक प्रति है, सेवा चर के साथ अब सेवा चर के साथ कुछ भी नहीं है और इच्छा जब सेवा var करता है तो नहीं बदला जाता है।

जब $ स्कोप var बराबर और ऑब्जेक्ट सेट किया जाता है, तो इसे संदर्भ द्वारा असाइन किया जाता है। इसका अर्थ यह है कि जब सेवा ऑब्जेक्ट (ध्यान दें कि सेवा एक ऑब्जेक्ट है क्योंकि यह नए कीवर्ड के साथ तत्काल है और आप उस ऑब्जेक्ट को सेवा के अंदर "इस" के साथ संदर्भित कर सकते हैं) या संदर्भित सेवा पर किसी ऑब्जेक्ट को बदल दिया गया है, उन ऑब्जेक्ट्स का संदर्भ देने वाले किसी भी $ स्कोप वेरिएबल भी अपडेट होंगे।

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