javascript - পরিষেবা HTTP প্রক্রিয়া প্রতিক্রিয়া




angularjs angular-http (8)

আপনার অ্যারেতে UI টি বাঁধন করার সময় আপনি নিশ্চিত করতে চাইবেন যে আপনি সেই একই অ্যারেটি সরাসরি দৈর্ঘ্য 0 সেট করে এবং অ্যারেতে ধাক্কা দিয়ে সরাসরি আপডেট করুন।

এটির পরিবর্তে (যা data একটি ভিন্ন অ্যারে রেফারেন্স সেট data যা আপনার UI সম্পর্কে জানবে না):

 myService.async = function() {
    $http.get('test.json')
    .success(function (d) {
      data = d;
    });
  };

এটা চেষ্টা কর:

 myService.async = function() {
    $http.get('test.json')
    .success(function (d) {
      data.length = 0;
      for(var i = 0; i < d.length; i++){
        data.push(d[i]);
      }
    });
  };

এখানে একটি বেহুদা যা একটি নতুন অ্যারের বনাম খালি এবং বিদ্যমান এক যোগ করার মধ্যে পার্থক্য দেখায়। আমি আপনার plnkr কাজ করতে পারে না কিন্তু আশা করি এটি আপনার জন্য কাজ করে!

আমি সাম্প্রতিক সময়ে এই সমস্যার সম্মুখীন একটি বিস্তারিত বিবরণ পোস্ট করেছি। আমি একটি প্রকৃত $http অনুরোধ পাঠাতে পারিনি, আমি অ্যাসিঙ্ক্রোনাস আচরণ অনুকরণ করতে টাইমআউট ব্যবহার করেছিলাম। আমার মডেল থেকে দেখতে ডেটা বাইন্ডিং @Gloopy এর সাহায্যে সঠিক কাজ করছে

এখন, যখন আমি $timeout (স্থানীয়ভাবে পরীক্ষিত) পরিবর্তে $http ব্যবহার করি, তখন আমি দেখতে পেলাম অ্যাসিঙ্ক্রোনাস অনুরোধ সফল হয়েছে এবং আমার পরিষেবাতে জেসন প্রতিক্রিয়া সহ data ভর্তি। কিন্তু, আমার ভিউ আপডেট করা হয় না।

here Plunkr আপডেট


আমারও একই সমস্যা ছিল, কিন্তু যখন আমি ইন্টারনেটে সার্ফিং করছিলাম তখন বুঝতে পারলাম যে $ http ডিফল্টরূপে ফেরত ফেরত দিচ্ছে, তাহলে আমি "তথ্য" ফেরার পর এটি "তারপর" ব্যবহার করতে পারি। কোডটি দেখুন:

 app.service('myService', function($http) {
       this.getData = function(){
         var myResponseData = $http.get('test.json').then(function (response) {
            console.log(response);.
            return response.data;
          });
         return myResponseData;

       }
});    
 app.controller('MainCtrl', function( myService, $scope) {
      // Call the getData and set the response "data" in your scope.  
      myService.getData.then(function(myReponseData) {
        $scope.data = myReponseData;
      });
 });

আমি ভালো কিছু মনে একটি অনেক ভাল উপায়:

সার্ভিস:

app.service('FruitsManager',function($q){

    function getAllFruits(){
        var deferred = $q.defer();

        ...

        // somewhere here use: deferred.resolve(awesomeFruits);

        ...

        return deferred.promise;
    }

    return{
        getAllFruits:getAllFruits
    }

});

এবং নিয়ামক আপনি কেবল ব্যবহার করতে পারেন:

$scope.fruits = FruitsManager.getAllFruits();

Angular স্বয়ংক্রিয়ভাবে $scope.fruits মধ্যে সমাধান awesomeFruits করা হবে।


আমি সত্যিই সত্যটি পছন্দ করি না, কারণ "প্রতিশ্রুতি" জিনিসগুলি করার উপায়টি, $ http ব্যবহার করে পরিষেবাটির গ্রাহককে প্রতিক্রিয়াটি কিভাবে আনপ্যাক করবেন সে সম্পর্কে "জানা" আছে।

আমি শুধু কিছু কল করতে এবং তথ্য পেতে চাই, পুরানো $scope.items = Data.getData(); উপায়, যা এখন বর্জন করা হয়

আমি কিছুক্ষণের জন্য চেষ্টা করেছি এবং নিখুঁত সমাধান নিয়ে আসিনি, কিন্তু এখানে আমার সেরা শট ( Plunker )। এটা কেউ দরকারী হতে পারে।

app.factory('myService', function($http) {
  var _data;  // cache data rather than promise
  var myService = {};

  myService.getData = function(obj) { 
    if(!_data) {
      $http.get('test.json').then(function(result){
        _data = result.data;
        console.log(_data);  // prove that it executes once
        angular.extend(obj, _data);
      }); 
    } else {  
      angular.extend(obj, _data);
    }
  };

  return myService;
}); 

তারপর নিয়ামক:

app.controller('MainCtrl', function( myService,$scope) {
  $scope.clearData = function() {
    $scope.data = Object.create(null);
  };
  $scope.getData = function() {
    $scope.clearData();  // also important: need to prepare input to getData as an object
    myService.getData($scope.data); // **important bit** pass in object you want to augment
  };
});

ত্রুটি আমি ইতিমধ্যে স্পট করতে পারেন

  • আপনি যে বস্তুটিতে যোগ করেছেন তা আপনাকে পাস করতে হবে, যা কৌণিকের স্বজ্ঞাত বা সাধারণ প্যাটার্ন নয়
  • getData শুধুমাত্র একটি বস্তুর আকারে obj প্যারামিটার গ্রহণ করতে পারে (যদিও এটি একটি অ্যারে গ্রহণ করতে পারে), যা অনেক অ্যাপ্লিকেশনের জন্য কোন সমস্যা হবে না, তবে এটি একটি গুরুতর সীমাবদ্ধতা
  • আপনাকে ইনপুট অবজেক্ট $scope.data দিয়ে = {} দিয়ে এটি একটি বস্তু তৈরি করতে হবে (মূলত কি $scope.clearData() উপরে আছে, অথবা = [] একটি অ্যারের জন্য, অথবা এটি কাজ করবে না (আমরা ' ইতিমধ্যে কি তথ্য আসছে সম্পর্কে কিছু অনুমান হচ্ছে)। আমি getData এই প্রস্তুতি পদক্ষেপ করতে চেষ্টা, কিন্তু কোন ভাগ্য।

যাইহোক, এটি এমন একটি প্যাটার্ন সরবরাহ করে যা কন্ট্রোলারকে "প্রতিশ্রুতি ছাড়িয়ে ফেলার" বয়লারপ্লেটটি সরিয়ে দেয় এবং এটি DRY রাখার সময় আপনি একাধিক জায়গায় $ http থেকে প্রাপ্ত নির্দিষ্ট ডেটা ব্যবহার করতে চাইলে ক্ষেত্রে কার্যকর হতে পারে।


এটা সহজ হতে দিন। এটা হিসাবে হিসাবে সহজ

  1. আপনার সেবা ফিরে promise ( then পরিষেবা ব্যবহার করার প্রয়োজন নেই)
  2. then আপনার নিয়ামক ব্যবহার করুন

ডেমো। http://plnkr.co/edit/cbdG5p?p=preview

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

app.factory('myService', function($http) {
  return {
    async: function() {
      return $http.get('test.json');  //1. this returns promise
    }
  };
});

app.controller('MainCtrl', function( myService,$scope) {
  myService.async().then(function(d) { //2. so you can use .then()
    $scope.data = d;
  });
});

এটি অ্যাসিঙ্ক্রোনাস হিসাবে, অজ্যাক্স কল সম্পূর্ণ হওয়ার আগে $scope ডেটা পেয়ে যাচ্ছে।

promise তৈরি করার জন্য আপনি আপনার পরিষেবাতে $q ব্যবহার করতে পারেন এবং এটি কন্ট্রোলারকে ফেরত দিতে পারেন, এবং নিয়ামক then() promise বিরুদ্ধে কল then() মধ্যে ফলাফলটি পেতে পারেন।

আপনার সেবা,

app.factory('myService', function($http, $q) {
  var deffered = $q.defer();
  var data = [];  
  var myService = {};

  myService.async = function() {
    $http.get('test.json')
    .success(function (d) {
      data = d;
      console.log(d);
      deffered.resolve();
    });
    return deffered.promise;
  };
  myService.data = function() { return data; };

  return myService;
});

তারপর, আপনার নিয়ামক মধ্যে:

app.controller('MainCtrl', function( myService,$scope) {
  myService.async().then(function() {
    $scope.data = myService.data();
  });
});

তোশ শিমায়ামার একটি সমাধান আছে তবে আপনি যদি $ এইচটিএমএল প্রতিশ্রুতি ফিরিয়ে দেন এবং এই প্রতিশ্রুতিগুলি মূল্য ফেরত দিতে পারে তবে আপনি অনেকগুলি সহজ করতে পারেন:

app.factory('myService', function($http, $q) {
  myService.async = function() {
    return $http.get('test.json')
    .then(function (response) {
      var data = reponse.data;
      console.log(data);
      return data;
    });
  };

  return myService;
});

app.controller('MainCtrl', function( myService,$scope) {
  $scope.asyncData = myService.async();
  $scope.$watch('asyncData', function(asyncData) {
    if(angular.isDefined(asyncData)) {
      // Do something with the returned data, angular handle promises fine, you don't have to reassign the value to the scope if you just want to use it with angular directives
    }
  });

});

Coffeescript একটি সামান্য বিক্ষোভ: http://plunker.no.de/edit/ksnErx?live=preview

আপনার plunker আমার পদ্ধতি সঙ্গে আপডেট: http://plnkr.co/edit/mwSZGK?p=preview


যতদূর পর্যন্ত পরিষেবাটিতে প্রতিক্রিয়া সম্পর্কিত ক্যাশিং উদ্বিগ্ন, এখানে আরও একটি সংস্করণ যা আমি যতদূর দেখেছি তার তুলনায় আরো সোজা বলে মনে হচ্ছে:

App.factory('dataStorage', function($http) {
     var dataStorage;//storage for cache

     return (function() {
         // if dataStorage exists returned cached version
        return dataStorage = dataStorage || $http({
      url: 'your.json',
      method: 'GET',
      cache: true
    }).then(function (response) {

              console.log('if storage don\'t exist : ' + response);

              return response;
            });

    })();

});

এই সেবা ক্যাশে তথ্য বা $http.get ফিরে $http.get ;

 dataStorage.then(function(data) {
     $scope.data = data;
 },function(e){
    console.log('err: ' + e);
 });




angular-http