$ রাষ্ট্র (ইউআই-রাউটার) $ এইচটিপি ইন্টারসেপ্টারে ইনজেকশনের ফলে বৃত্তাকার নির্ভরতা হয়


120

আমি যা অর্জন করার চেষ্টা করছি

যদি কোনও $ HTTP অনুরোধ 401 ত্রুটি প্রত্যাবর্তন করে তবে আমি একটি নির্দিষ্ট রাজ্যে (লগইন) স্থানান্তর করতে চাই। তাই আমি একটি $ http ইন্টারসেপ্টর তৈরি করেছি।

সমস্যাটি

আমি যখন ইন্টারসেপ্টারে '$ রাষ্ট্র' inোকানোর চেষ্টা করি তখন আমি একটি বৃত্তাকার নির্ভরতা পাই। কেন এবং কীভাবে আমি এটি ঠিক করব?

কোড

//Inside Config function

    var interceptor = ['$location', '$q', '$state', function($location, $q, $state) {
        function success(response) {
            return response;
        }

        function error(response) {

            if(response.status === 401) {
                $state.transitionTo('public.login');
                return $q.reject(response);
            }
            else {
                return $q.reject(response);
            }
        }

        return function(promise) {
            return promise.then(success, error);
        }
    }];

    $httpProvider.responseInterceptors.push(interceptor);

উত্তর:


213

ঠিক করা

$injectorপরিষেবাটি একটি রেফারেন্স পেতে পরিষেবাটি ব্যবহার করুন $state

var interceptor = ['$location', '$q', '$injector', function($location, $q, $injector) {
    function success(response) {
        return response;
    }

    function error(response) {

        if(response.status === 401) {
            $injector.get('$state').transitionTo('public.login');
            return $q.reject(response);
        }
        else {
            return $q.reject(response);
        }
    }

    return function(promise) {
        return promise.then(success, error);
    }
}];

$httpProvider.responseInterceptors.push(interceptor);

কারণ

কৌণিক- ui- রাউটারটি$http নির্ভরতা হিসাবে পরিষেবাটিকে ইনজেকশনে দেয় $TemplateFactoryযার পরে ইন্টারসেপ্টার প্রেরণের পরে নিজের $httpমধ্যে একটি বিজ্ঞপ্তি রেফারেন্স তৈরি করে $httpProvider

আপনি যদি $httpপরিষেবাটিকে সরাসরি কোনও ইন্টারসেপ্টারে সরাসরি ইনজেক্ট করার চেষ্টা করেন তবে একই বৃত্তাকার নির্ভরতা ব্যতিক্রম ছুঁড়ে ফেলা হবে ।

var interceptor = ['$location', '$q', '$http', function($location, $q, $http) {

উদ্বেগ বিচ্ছেদ

বিজ্ঞপ্তি নির্ভরতা ব্যতিক্রমগুলি ইঙ্গিত করতে পারে যে আপনার আবেদনের মধ্যে উদ্বেগের মিশ্রণ রয়েছে যা স্থায়িত্বের সমস্যার কারণ হতে পারে। আপনি যদি নিজেকে এই ব্যতিক্রমটির সাথে সন্ধান করেন তবে আপনার আর্কিটেকচারের দিকে নজর দেওয়ার জন্য আপনার সময় নেওয়া উচিত যাতে নিশ্চিত হয়ে যায় যে আপনি কোনও নির্ভরতা এড়িয়ে গেছেন যা তাদের উল্লেখ করা শেষ হয়।

@ স্টেফেন ফ্রিডরিচের উত্তর

আমি নীচের উত্তরের সাথে একমত যে $injectorসরাসরি পছন্দসই পরিষেবাদির রেফারেন্স পেতে ব্যবহার করা আদর্শ নয় এবং এটি একটি বিরোধী নিদর্শন হিসাবে বিবেচিত হতে পারে।

একটি ইভেন্ট নির্গমন একটি আরও মার্জিত এবং decoupled সমাধান।


1
এটি কৌনিক 1.3 এর জন্য কীভাবে সামঞ্জস্য করা হবে, যেখানে 4 টি বিভিন্ন ফাংশন ইন্টারসেপ্টারে পাস করা হয়েছে?
ম্যাকিয়েজ গুরবান

3
ব্যবহারটি একই রকম হবে, আপনি $injectorপরিষেবাটি আপনার ইন্টারসেপ্টারে ইনজেকশন দিয়ে কল করুন $injector.get()যেখানে আপনাকে $stateপরিষেবাটি পেতে হবে call
জোনাথন পালাম্বো

আমি << সংজ্ঞায়িত নয় >> হিসাবে $ injectot.get ("$ state") পেয়েছি, আপনি কি দয়া করে বলতে পারবেন সমস্যাটি কি হতে পারে?
সন্দীপ কালে

এটি অবশ্যই একটি সহজ পরিস্থিতি যখন একটি সহজ পরিস্থিতি, তবে আপনি যখন এটি চালাবেন এটি এটি একটি চিহ্ন যে আপনি সত্যই আপনার কোডের কোথাও একটি বিজ্ঞপ্তি নির্ভরতা তৈরি করেছেন যা এটির ডিআই দিয়ে অ্যাংুলারজেএসে করা সহজ। মিসকো হেভরি তার ব্লগে এটি খুব ভালভাবে ব্যাখ্যা করেছেন ; আপনার কোডটি উন্নত করতে আপনি এটি পড়ার জন্য অত্যন্ত পরামর্শ দিন।
জেডি স্মিথ

2
$httpProvider.responseInterceptors.pushআপনি যদি কৌণিক পরবর্তী সংস্করণ ব্যবহার করছেন তবে আর কাজ করবেন না। $httpProvider.interceptors.push()পরিবর্তে ব্যবহার করুন। আপনাকে interceptorপাশাপাশি পরিবর্তন করতে হবে । যাইহোক, দুর্দান্ত উত্তরের জন্য ধন্যবাদ! :)
shyam

25

প্রশ্নটি AngularJS এর একটি সদৃশ : এইচটিটিপি ইন্টারসেপ্টারে ইনজেকশন পরিষেবা (বিজ্ঞপ্তি নির্ভরতা)

আমি এই থ্রেড থেকে আমার উত্তর এখানে পোস্ট করছি:

একটি ভাল ফিক্স

আমি মনে করি সরাসরি ইনজেক্টর ব্যবহার করা একটি অ্যান্টিপ্যাটার্ন।

বিজ্ঞপ্তি নির্ভরতা ভাঙার একটি উপায় হল একটি ইভেন্ট ব্যবহার করা: $ রাজ্যের ইনজেক্ট করার পরিবর্তে, ইনজেক্ট $ রুটস্কোপ। সরাসরি পুনর্নির্দেশের পরিবর্তে, করুন

this.$rootScope.$emit("unauthorized");

যোগ

angular
    .module('foo')
    .run(function($rootScope, $state) {
        $rootScope.$on('unauthorized', () => {
            $state.transitionTo('login');
        });
    });

এইভাবে আপনি উদ্বেগগুলি পৃথক করেছেন:

  1. একটি 401 প্রতিক্রিয়া সনাক্ত করুন
  2. লগইন পুনর্নির্দেশ

2
প্রকৃতপক্ষে, এই প্রশ্নটি এই প্রশ্নের সদৃশ, কারণ এই প্রশ্নটি হওয়ার আগেই এই প্রশ্নটি করা হয়েছিল। আপনার মার্জিত স্থিরতা পছন্দ করুন, সুতরাং একটি উপবিষ্টতা আছে। ;-)
অ্যারন গ্রে

1
আমি এটি কোথায় রাখব সে সম্পর্কে আমি বিভ্রান্তি বোধ করছি $
অ্যালেক্স

16

আমি বর্তমান অবস্থা বাঁচানোর চেষ্টা না করা অবধি জোনাথনের সমাধান দুর্দান্ত ছিল। ইন নামঃ ui-রাউটার v0.2.10 বর্তমান রাষ্ট্র উপর আটককারী প্রারম্ভিক পৃষ্ঠা লোড জনবহুল হবে বলে মনে হচ্ছে না।

যাইহোক, আমি পরিবর্তে $ stateChangeError ইভেন্ট ব্যবহার করে এটি সমাধান করেছি । $ StateChangeError ইভেন্টে উভয় দেয় করার এবং থেকে রাজ্যের সেইসাথে ত্রুটি। এটা বেশ নিফটি।

$rootScope.$on('$stateChangeError',
    function(event, toState, toParams, fromState, fromParams, error){
        console.log('stateChangeError');
        console.log(toState, toParams, fromState, fromParams, error);

        if(error.status == 401){
            console.log("401 detected. Redirecting...");

            authService.deniedState = toState.name;
            $state.go("login");
        }
    });

আমি এই সম্পর্কে একটি সমস্যা জমা দিয়েছেন ।
জাস্টিন Wrobel

আমি মনে করি এনজিআরসোর্সের মাধ্যমে এটি সম্ভব নয় কেননা এটি সর্বদা অ্যাসিনক্রোন হয়? আমি কিছু স্টাফ চেষ্টা করেছি তবে রাষ্ট্রীয় পরিবর্তন রোধ করতে আমি রিসোর্স কলটি পাই না ...
বাসটিয়ান

4
আপনি যদি এমন কোনও অনুরোধকে আটকাতে চান যা একটি রাষ্ট্র পরিবর্তন পরিবর্তন করে না?
শিক্লোশি

আপনি উপরের স্টিফেন ফ্রিডরিচের মতো একই পন্থাটি ব্যবহার করতে পারেন যা আসলে এটির সাথে সাদৃশ্যযুক্ত তবে একটি কাস্টম ইভেন্ট ব্যবহার করে।
সাইয়ানকোডার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.