2016-03-19 7 views
5

एनजी-फाइल-अपलोड (https://github.com/danialfarid/ng-file-upload) के लिए नमूना उपयोग कोड युक्त अधिकांश फ़िड्स में (http://jsfiddle.net/danialfarid/maqbzv15/1118/) की तरह, अपलोड प्रतिक्रिया कॉलबैक फ़ंक्शन $timeout सेवा कॉल में अपना कोड लपेटते हैं, लेकिन इन कॉलों में कोई देरी नहीं होती है पैरामीटर के लिए $timeout (https://docs.angularjs.org/api/ng/service/ $ का समय समाप्त) संकेत मिलता है कि देरी वैकल्पिक है, लेकिन तुम क्यों $timeout करने के लिए एक कॉल करने के लिए नहीं तो कोड जा रहा रन देरी करने के लिए चाहते हो जाएगा में पारित कर दिया।

Angular.js डॉक्स। निम्नलिखित के बजाय दूसरे शब्दों में, क्यों नहीं एक के बाद:

//inject angular file upload directives and services. 
var app = angular.module('fileUpload', ['ngFileUpload']); 

app.controller('MyCtrl', ['$scope', 'Upload', '$timeout', function ($scope, Upload, $timeout) { 
$scope.uploadPic = function(file) { 
file.upload = Upload.upload({ 
    url: 'https://angular-file-upload-cors-srv.appspot.com/upload', 
    data: {username: $scope.username, file: file}, 
}); 

file.upload.then(function (response) { 
    $timeout(function() { 
    file.result = response.data; 
    }); 
}, function (response) { 
    if (response.status > 0) 
    $scope.errorMsg = response.status + ': ' + response.data; 
}, function (evt) { 
    // Math.min is to fix IE which reports 200% sometimes 
    file.progress = Math.min(100, parseInt(100.0 * evt.loaded/evt.total)); 
}); 
} 
}]); 

वहाँ इन सभी उदाहरणों में $timeout आवरण के लिए किसी भी कारण है? चाहेंगे उसके स्थान पर निम्नलिखित file.upload कॉल काम ?:

file.upload.then(function (response) { 
    file.result = response.data; 
}, function (response) { 
    if (response.status > 0) 
    $scope.errorMsg = response.status + ': ' + response.data; 
}, function (evt) { 
    // Math.min is to fix IE which reports 200% sometimes 
    file.progress = Math.min(100, parseInt(100.0 * evt.loaded/evt.total)); 
}); 

संपादित करें: मैं देख सकता हूँ यह $timeout आवरण के बिना चलाने के लिए प्रतीत होता है कि है, लेकिन तथ्य यह है कि यह सब उदाहरण में शामिल है मुझे लगता है कि यह जानबूझकर है बनाता है, जिसका अर्थ है कि यहां एक सुरक्षा/मजबूती/ब्राउज़र संगतता एज केस है जो मुझे समझ में नहीं आता है।

उत्तर

10

यह कोणीय के पाचन चक्र के साथ सब कुछ करने के लिए है। मैं यह समझाने के लिए कि पाचन चक्र क्या है, मैं इसे एक उदाहरण के साथ प्रदर्शित करने की कोशिश करूंगा। निम्न कोड की कल्पना करें:

angular.module('app', []).controller('TestController', ['$scope', function($scope){ 
    $scope.name = 'Tom'; 
    setTimeout(function(){ 
     $scope.name = 'Bob'; 
    }, 2000); 
}]); 

इस कोड के साथ एक निहित समस्या है। जितना हम 2 सेकंड के बाद $scope.name के चर को बदलते हैं, कोणीय इस परिवर्तन से $scope.name पर पूरी तरह से अनजान है। अब आप निम्न उदाहरण पर विचार करें, जहां हम $timeout बजाय का उपयोग करें:

angular.module('app', []).controller('TestController', ['$scope', '$timeout', function($scope, $timeout){ 
    $scope.name = 'Tom'; 
    $timeout(function(){ 
     $scope.name = 'Bob'; 
    }, 2000); 
}]); 

कोणीय, हालांकि दो सेकंड के बाद अज्ञात फ़ंक्शन कॉल करेंगे, यह तो कोणीय के चक्र को पचाने आरंभ होता है। $timeout और setTimeout के बीच यह मुख्य अंतर है, पाचन चक्र चलाया जा रहा है।

डाइजेस्ट चक्र (केवल डाला जाता है) कोणीय सभी निरीक्षक (बाइंडिंग) पर जा रहा है, किसी भी बदलाव की जांच कर रहा है और जहां एप्राइपियेट फिर से प्रस्तुत किया जा रहा है। आपने $scope.$apply कहीं और उल्लेख किया होगा - यह पाचन चक्र शुरू करने का तरीका है।

आपके द्वारा प्रदान किए गए उदाहरण के संबंध में: यदि $timeout का उपयोग नहीं किया गया था, तो कोणीय को पता नहीं होगा कि कोई भी परिवर्तन किया गया है और इस तरह, आपका दृश्य अपडेट नहीं होगा। मैंने पहले $scope.$apply का उल्लेख किया है ताकि आप सोच रहे हों कि हम इसका उपयोग क्यों नहीं करते हैं? $scope.$apply का उपयोग करने में समस्या यह है कि आप यह सुनिश्चित नहीं कर सकते कि एक पाचन चक्र पहले से ही प्रगति पर नहीं है। अगर आप इसे कॉल करते समय कॉल करते हैं, तो आपको एक त्रुटि दिखाई देगी "$digest is already in progress"। $timeout केवल वर्तमान चक्र के बाद ही चलाएगा और इस तरह, यह त्रुटि नहीं होगी।

लोग अक्सर $timeout का उपयोग एंगुलर को सूचित करने में देरी के बिना करते हैं कि किसी तीसरे पक्ष (जैसे आपकी फ़ाइल अपलोडर) में परिवर्तन किया गया है, अन्यथा यह नहीं पता था कि यह हुआ था।

उम्मीद है कि यह चीजों को साफ़ करता है।

टॉम

+0

इस उत्तर के लिए धन्यवाद। हालांकि, जैसा कि ओपी ने स्पष्ट रूप से उल्लेख किया था, "यह $ टाइमआउट रैपर के बिना चल रहा है"। क्या आप कुछ प्रकाश डाल सकते हैं कि यह अभी भी '$ टाइमआउट' रैपर के बिना क्यों काम करता है? – rinogo

+2

इसके अलावा, आपकी ज़रूरतों के आधार पर, आप '$ टाइमआउट' के बजाय '$ scope। $ EvalAsync()' का उपयोग करने पर विचार कर सकते हैं। स्रोत: https://www.bennadel.com/blog/2605-scope-evalasync-vs-timeout-in-angularjs.htm – rinogo

+2

@rinogo मैं केवल कल्पना कर सकता हूं कि कहीं और कोड का एक टुकड़ा पाचन चक्र शुरू कर रहा है। एक पाचन शुरू होने तक कोणीय को '$ स्कोप' में परिवर्तनों के बारे में जागरूक होना असंभव है। – maddockst

1

$timeout किसी भी कॉलबैक को असीमित रूप से आह्वान करने के लिए उपयोग किया जा सकता है। जैसे

$timeout(function callback() { 
    // code run asynchronously... 
}); 

इसका मतलब है कि आपके जावाबैक को कॉल करने से पहले सभी जावास्क्रिप्ट चलाना समाप्त हो जाएगा। पैरामीटर को timeout में जोड़ने से कॉलबैक आमंत्रण लगभग उतना ही अधिक हो जाएगा, लेकिन आप अभी भी असीमित व्यवहार प्राप्त करते हैं चाहे delay प्रदान किया गया हो या नहीं।

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