2012-06-21 27 views
24

पर $ संसाधन से प्राप्त मूल्य को अपडेट नहीं कर रहा है मुझे कस्टम निर्देशों के साथ कोई समस्या है जो मुझे पागल कर रहा है। मैं निम्नलिखित कस्टम बनाने के लिए कोशिश कर रहा हूँ (विशेषता) के निर्देश:

angular.module('componentes', []) 
    .directive("seatMap", function(){ 
     return { 
      restrict: 'A', 
      link: function(scope, element, attrs, controller){ 

       function updateSeatInfo(scope, element){ 
        var txt = ""; 
        for (var i in scope.seats) 
         txt = txt + scope.seats[i].id + " "; 
        $(element).text("seat ids: "+txt); 
       } 

       /* 
        // This is working, but it's kind of dirty... 
        $timeout(function(){updateSeatInfo(scope,element);}, 1000); 
       */ 

       scope.$watch('seats', function(newval, oldval){ 
        console.log(newval, oldval); 
        updateSeatInfo(scope,element); 
       }); 
      } 
     } 
    }); 

यह "विशेषता-प्रकार" निर्देश (seatMap कहा जाता है) (एक थिएटर के लिए, उदाहरण के लिए) सीट आईडी की एक सूची दिखाने के लिए कोशिश कर रहा है जो मैं सर्वर से $ संसाधन सेवा (नीचे कोड देखें) के माध्यम से एक div (तत्व) में लाऊंगा।

मैं इसे उपयोग कर रहा हूँ इस सरल आंशिक एचटीएमएल के साथ:

<div> 
    <!-- This is actually working --> 
    <ul> 
     <li ng-repeat="seat in seats">{{seat.id}}</li> 
    </ul> 

    <!-- This is not... --> 
    <div style="border: 1px dotted black" seat-map></div> 
</div> 

और यह नियंत्रक जो गुंजाइश लोड कर रहा है है:

function SeatsCtrl($scope, Seats) { 
    $scope.sessionId = "12345"; 
    $scope.zoneId = "A"; 
    $scope.seats = Seats.query({sessionId: $scope.sessionId, zoneId: $scope.zoneId}); 
    $scope.max_seats = 4; 
} 

कहाँ "सीटें" $ का उपयोग कर एक साधारण सेवा है संसाधन सर्वर से एक JSON लाने के लिए

angular.module('myApp.services', ['ngResource']) 
    .factory('Seats', function($resource){ 
     return $resource('json/seats-:sessionId-:zoneId.json', {}, {}); 
    }) 
; 

app.js (asientos_libres.html आंशिक मैं ख है है een का प्रयोग करके):

angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'componentes']). 
    config(['$routeProvider', function($routeProvider) { 
    $routeProvider.when('/view1', {templateUrl: 'partials/asientos_libres.html', controller: SeatsCtrl}); 
    $routeProvider.otherwise({redirectTo: '/view1'}); 
    }]); 

समस्या है, भले ही मैं एक "गुंजाइश $ घड़ी।" निर्देश का लिंक समारोह में स्थापित किया ताकि गुंजाइश जांच कर सकते हैं "सीटों" विशेषता को अपडेट करने बदली है या नहीं आईडी की सूची, यह इस समय काम नहीं कर रहा है $ scope.seats नियंत्रक में बदल रहा है (जब हम "क्वेरी" कहते हैं)।

आप कोड में देख सकते हैं, मैं $ टाइमआउट का उपयोग कर "updateSeatInfo" के प्रक्षेपण में देरी करने का प्रयास किया है, लेकिन मुझे डर है कि यह अब तक का सबसे स्मार्ट समाधान नहीं है हूँ ...

मैं भी करने की कोशिश की JSON अनुरोध न करने के लिए, लेकिन $ scope.seats में हार्ड-कोडित शब्दकोश का उपयोग करें और यह काम करता है, इसलिए ऐसा लगता है कि यह सिंक्रनाइज़ेशन का विषय है।

नोट: अद्यतनSeatInfo केवल एक परीक्षण कार्य है, वास्तविक फ़ंक्शन जिसका मैं उपयोग करूंगा वह थोड़ा अधिक जटिल है।

इससे निपटने के बारे में कोई विचार?

बहुत पहले धन्यवाद!

संपादित करें 1: जोड़ा गया app.js, जहां मैं SeatsCtrl को कॉल करने के लिए राउटर का उपयोग कर रहा हूं, सलाह के लिए सुप्र के लिए धन्यवाद। हालांकि, मुझे अभी भी एक ही समस्या है।

संपादित करें 2: हल किया गया! (?) ठीक है! ऐसा लगता है कि मुझे एक समाधान मिला, जो कि सबसे अच्छा नहीं हो सकता है, लेकिन यह ठीक से काम कर रहा है! :) जहां तक ​​मैं यहां देख सकता था http://docs.angularjs.org/api/ng.$timeout, हम $ timeout (setTimeout पर एक रैपर) का उपयोग कर देरी के साथ कर सकते हैं! यह बहुत अच्छा है क्योंकि हम $ timeout के अंदर हमारे कोड के निष्पादन में कृत्रिम रूप से देरी नहीं कर रहे हैं, लेकिन हम निर्देश बना रहे हैं कि जब तक एसिंक्रोनस अनुरोध समाप्त नहीं हो जाता है।

आशा है कि यह भी लंबे समय से प्रतीक्षा अनुरोधों के लिए काम करेंगे ...

कोई इसे ठीक करने के लिए एक बेहतर तरीका जानता है, तो कृपया बताएं!

उत्तर

57

मुद्दा यह है कि घड़ी डिफ़ॉल्ट रूप से वस्तु के बजाय संदर्भ तुलना है। इसके बजाय मूल्य की तुलना करने के अंत में सत्य जोड़ें।

scope.$watch('seats', function(newval, oldval){ 
       console.log(newval, oldval); 
       updateSeatInfo(scope,element); 
      }, true); 
+6

सावधानी का एक शब्द: इस तरह की गहरी तुलना में प्रदर्शन लागत है। यह एक समस्या है जब एक वस्तु के बजाए वस्तुओं का संग्रह गहराई से देखता है, लेकिन यह ध्यान में रखना महत्वपूर्ण है। –

0

मैं नहीं देख सकता कि आप SeatsCtrl -controller कहीं भी उपयोग कर रहे हैं?इसका उपयोग कैसे किया जा रहा है? और क्या आपने सत्यापित किया है कि यह सक्रिय है, और वास्तव में क्वेरी वास्तव में की जाती है?

सीट्सकूट उपयोग में है या नहीं, यह जांचने का सबसे तेज़ तरीका है कि बस इसके अंदर console.log('SeatsCtrl actived!'); जोड़ें। यदि ऐसा नहीं है, तो ng-controller="SeatsCtrl" को div पर जोड़ें।

आप सीधे नियंत्रक के अंदर सीटों पर घड़ी-और-लॉग भी डाल सकते हैं ताकि यह सुनिश्चित किया जा सके कि यह स्कोपिंग के साथ कोई समस्या नहीं है।

+0

ठीक है, मैं वास्तव में app.js में राउटर के माध्यम से SeatsCtrl का उपयोग करता हूं, क्षमा करने के लिए खेद है। मैंने इसे स्पष्ट करने के लिए पोस्ट संपादित किया है। – Sheniff

+0

मैं देखता हूं। कोई भी कम नहीं, क्या आपने यह सत्यापित किया कि नियंत्रक चलता है, और यह पूछताछ सीटों की अपेक्षा की जा रही है? जैसे मैंने कहा, SeatsCtrl के अंदर एक घड़ी जोड़ने से कम से कम यह पता चलता है कि क्वेरी चलनी चाहिए या नहीं, इस स्थिति में शायद यह स्कोपिंग के साथ एक समस्या है। – Supr

+0

चेक किया गया। क्वेरी ** चल रही है, लेकिन ** केवल अगर मैं टाइमआउट का उपयोग करता हूं। यह वही मुद्दा है क्योंकि यह निर्देश में हो रहा है। ऐसा लगता है कि यह अजाक्स ($ प्रतिक्रिया के माध्यम से) के माध्यम से डेटा प्राप्त करने के लिए पूरी तरह से सिंक्रनाइज़ेशन का मामला है ... इस तरह से दायरा ठीक है। – Sheniff

0

मुझे यह समस्या भी है। मुझे लगता है कि यह कोणीय में एक समस्या है। गिटहब पर "beef up $resource futures" पर एक टिकट है जो शायद इस मुद्दे को संबोधित करेगा, जैसा कि आपको वास्तव में आवश्यक है, आपके पास संसाधन के लिए वादे ऑब्जेक्ट तक पहुंच है।

या, जब तक वादे का समाधान नहीं हो जाता तब तक निरीक्षक आग तक इंतजार कर सकते थे।

इस बीच, इसे ठीक करने के लिए थोड़ा और सुरुचिपूर्ण तरीका जिसे टाइमआउट की आवश्यकता नहीं है, वह $ संसाधन पर सफलता कॉलबैक से देखी जा रही स्कोप संपत्ति को पुन: असाइन करना है। इससे वॉचर को उचित समय पर फिर से आग लग जाएगी।

कोई देरी नहीं होने वाला समय समाप्ति वर्तमान स्टैक के अंत में स्थगित फ़ंक्शन का मूल्यांकन डाल रहा है - आपके मामले में, आपका संसाधन तब तक हल किया जाना चाहिए, लेकिन सर्वर में होने पर यह समस्या हो सकती है सोमवार का मामला

उदाहरण:

$scope.myAttr = MyResource.fetch(
    function (resource) { $scope.myAttr = new MyResource(angular.copy(resource)); } 
); 
4

मुझे यह समस्या भी थी। यह इस तथ्य के कारण था कि मेरे चर को पहली बार दायरे में 'अपरिभाषित' परिभाषित नहीं किया गया था। लगता है कि अपरिभाषित चर पर काम नहीं करता है। सब के बाद स्पष्ट लगता है।

मैं पहली बार नियंत्रक द्वारा प्रभावी रूप से सेट होने पर ट्रिगर करने के लिए घड़ी का उपयोग करने का प्रयास कर रहा था। उदाहरण:

myApp.controller('Tree', function($scope, Tree) { 

Tree.get({}, 
function(data) { // SUCCESS 
    console.log("call api Tree.get succeed"); 
    $scope.treeData = data; 
}, 

function(data) { // FAILURE 
    console.log("call api Tree.get failed"); 
    $scope.treeData = {}; 
}); 
}); 

मैं सेवा कॉल करने से पहले एक खाली वस्तु के साथ मेरी चर आरंभ से इसे हल:

myApp.controller('Tree', function($scope, Tree) { 

$scope.treeData = {};  // HERE 

Tree.get({}, 
function(data) { // SUCCESS 
    console.log("call api Tree.get succeed"); 
    $scope.treeData = data; 
}, 

function(data) { // FAILURE 
    console.log("call api Tree.get failed"); 
    $scope.treeData = {}; 
}); 
}); 

उस मामले घड़ी में चर में परिवर्तन का पता लगाने में सक्षम था।