ঝাঁকুনি প্রতিরোধে মডেল লোড না হওয়া পর্যন্ত অ্যাঙ্গুলারজেএস রুটের পরিবর্তনকে বিলম্বিত করা


321

আমি ভাবছি যে অ্যাঙ্গুলারজেএস-এর জন্য কোনও মডেল এবং এর সম্পর্কিত পরিষেবাদিগুলি ব্যবহার করে এর ডেটা সংগ্রহ না করা পর্যন্ত কোনও নতুন রুট দেখাতে দেরি করার কোনও উপায় আছে (জিমেইলের মতো) is

উদাহরণস্বরূপ, যদি সেখানে ProjectsControllerসমস্ত প্রকল্পের তালিকাভুক্ত এবং যদি project_index.htmlএই প্রকল্পগুলি দেখায় যে টেম্পলেটটি ছিল, Project.query()নতুন পৃষ্ঠাটি দেখানোর আগে পুরোপুরি আনা হবে।

ততক্ষণে, পুরাতন পৃষ্ঠাটি এখনও দেখাতে থাকবে (উদাহরণস্বরূপ, যদি আমি অন্য পৃষ্ঠাটি ব্রাউজ করতাম এবং তারপরে এই প্রকল্পের সূচিটি দেখার সিদ্ধান্ত নিই)।

উত্তর:


374

$ রুটপ্রোভাইডার সমাধান সম্পত্তি ডেটা লোড না হওয়া পর্যন্ত রুট পরিবর্তনে বিলম্বের অনুমতি দেয়।

প্রথমে এর resolveমতো বৈশিষ্ট্যযুক্ত কোনও রুট সংজ্ঞায়িত করুন ।

angular.module('phonecat', ['phonecatFilters', 'phonecatServices', 'phonecatDirectives']).
  config(['$routeProvider', function($routeProvider) {
    $routeProvider.
      when('/phones', {
        templateUrl: 'partials/phone-list.html', 
        controller: PhoneListCtrl, 
        resolve: PhoneListCtrl.resolve}).
      when('/phones/:phoneId', {
        templateUrl: 'partials/phone-detail.html', 
        controller: PhoneDetailCtrl, 
        resolve: PhoneDetailCtrl.resolve}).
      otherwise({redirectTo: '/phones'});
}]);

লক্ষ করুন যে resolveসম্পত্তিটি রুটে সংজ্ঞায়িত করা হয়েছে।

function PhoneListCtrl($scope, phones) {
  $scope.phones = phones;
  $scope.orderProp = 'age';
}

PhoneListCtrl.resolve = {
  phones: function(Phone, $q) {
    // see: https://groups.google.com/forum/?fromgroups=#!topic/angular/DGf7yyD4Oc4
    var deferred = $q.defer();
    Phone.query(function(successData) {
            deferred.resolve(successData); 
    }, function(errorData) {
            deferred.reject(); // you could optionally pass error data here
    });
    return deferred.promise;
  },
  delay: function($q, $defer) {
    var delay = $q.defer();
    $defer(delay.resolve, 1000);
    return delay.promise;
  }
}

লক্ষ্য করুন যে কন্ট্রোলার সংজ্ঞায় একটি রেজোলিউশন অবজেক্ট থাকে যা এমন জিনিসগুলি ঘোষণা করে যা নিয়ন্ত্রণকারী কনস্ট্রাক্টরের কাছে উপলভ্য হওয়া উচিত। এখানে phonesনিয়ামকটি ইনজেক্ট করা হয় এবং এটি resolveসম্পত্তিতে সংজ্ঞায়িত হয় ।

resolve.phonesফাংশন একটি প্রতিশ্রুতি ফেরার জন্য দায়ী। সমস্ত প্রতিশ্রুতি সংগ্রহ করা হয় এবং সমস্ত প্রতিশ্রুতি সমাধানের পরে অবধি রুট পরিবর্তন বিলম্বিত হয়।

ওয়ার্কিং ডেমো: http://mhevery.github.com/angular-phonecat/app/#/فون সূত্র: https://github.com/mhevery/angular-phonecat/commit/ba33d3ec2d01b70eb5d3d531619bf90153496831


10
@ মিস্কোহেভরি - যদি আপনার কন্ট্রোলাররা মডিউলের অভ্যন্তরে থাকে এবং ফাংশন না করে স্ট্রিং হিসাবে সংজ্ঞায়িত হয় তবে। কীভাবে আপনি নিজের মতো সমাধানের বৈশিষ্ট্যটি সেটআপ করতে পারেন?
aar0n

53
angular.controller()টাইপ নিয়ামক সংজ্ঞাতে এটি কীভাবে ব্যবহৃত হয় ? স্টাফের মধ্যে $routeProvider, আমি ভেবেছিলাম আপনাকে কন্ট্রোলারের স্ট্রিং নাম ব্যবহার করতে হবে।
বেন লেশ

6
Angular.controller () ব্যবহার করে এবং AngularJS এর ​​সর্বশেষতম সংস্করণ সহ কোনও উদাহরণ?
লরেন্ট

22
@blesh, যখন আপনি ব্যবহার করবেন angular.controller(), আপনি এই ফাংশনটির ফলাফল একটি ভেরিয়েবল ( var MyCtrl = angular.controller(...)) এ নির্ধারণ করতে পারেন এবং তারপরে আরও ( MyCtrl.loadData = function(){..}) দিয়ে কাজ করতে পারেন । ডিম্বাণুর
পেট্রোটেকেক

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

51

এখানে একটি সর্বনিম্ন কার্যকারী উদাহরণ যা কৌণিক 1.0.2 এর জন্য কাজ করে

টেমপ্লেট:

<script type="text/ng-template" id="/editor-tpl.html">
    Editor Template {{datasets}}
</script>

<div ng-view>

</div>

javascript:

function MyCtrl($scope, datasets) {    
    $scope.datasets = datasets;
}

MyCtrl.resolve = {
    datasets : function($q, $http) {
        var deferred = $q.defer();

        $http({method: 'GET', url: '/someUrl'})
            .success(function(data) {
                deferred.resolve(data)
            })
            .error(function(data){
                //actually you'd want deffered.reject(data) here
                //but to show what would happen on success..
                deferred.resolve("error value");
            });

        return deferred.promise;
    }
};

var myApp = angular.module('myApp', [], function($routeProvider) {
    $routeProvider.when('/', {
        templateUrl: '/editor-tpl.html',
        controller: MyCtrl,
        resolve: MyCtrl.resolve
    });
});​

http://jsfiddle.net/dTJ9N/3/

প্রবাহিত সংস্করণ:

যেহেতু $ http () ইতিমধ্যে একটি প্রতিশ্রুতি দেয় (ওরফে পেছানো), আমাদের আসলে আমাদের নিজস্ব তৈরি করার দরকার নেই। সুতরাং আমরা MyCtrl সরল করতে পারি। সংকল্প:

MyCtrl.resolve = {
    datasets : function($http) {
        return $http({
            method: 'GET', 
            url: 'http://fiddle.jshell.net/'
        });
    }
};

$ HTTP () এর ফলাফলের মধ্যে ডেটা , স্থিতি , শিরোনাম এবং কনফিগারেশন অবজেক্ট রয়েছে তাই আমাদের মাইক্রিটিএল এর বডিটি এতে পরিবর্তন করতে হবে:

$scope.datasets = datasets.data;

http://jsfiddle.net/dTJ9N/5/


আমি এটির মতো কিছু করার চেষ্টা করছি তবে এটি সংজ্ঞায়িত না হওয়ায় 'ডেটাসেটগুলি' ইনজেকশনে সমস্যা হচ্ছে। কোন চিন্তা?
রব বাইগ্রাভ

আরে mb21, আমি মনে করি তুমি আমাকে এই প্রশ্নের সঙ্গে সাহায্য করতে সক্ষম হতে পারেন: stackoverflow.com/questions/14271713/...
winduptoy

কেউ আমাকে এই উত্তরটিকে app.controller ('MyCtrl') ফর্ম্যাটে রূপান্তর করতে সহায়তা করতে পারে? jsfiddle.net/5usya/1 আমার পক্ষে কাজ করেনি।
ব্যবহারকারী 1071182

আমি একটি ত্রুটি Unknown provider: datasetsProvider <- datasets
পেয়েছি

আপনি function($http) { return $http({method: 'GET', url: '/someUrl'}) .then( function(data){ return data;}, function(reason){return 'error value';} ); }
এটির

32

আমি কিছু লোককে কমাতে বন্ধুত্বপূর্ণ নির্ভরতা ইনজেকশন সহ কৌণিক.কন্ট্রোলার পদ্ধতিটি ব্যবহার করে এটি করতে জিজ্ঞাসা করছি। যেহেতু আমি এই কাজটি পেয়েছি আমি ফিরে এসে সাহায্য করতে বাধ্য বোধ করি। এখানে আমার সমাধান (মূল প্রশ্ন এবং মিসকো এর উত্তর থেকে গৃহীত):

angular.module('phonecat', ['phonecatFilters', 'phonecatServices', 'phonecatDirectives']).
  config(['$routeProvider', function($routeProvider) {
    $routeProvider.
      when('/phones', {
        templateUrl: 'partials/phone-list.html', 
        controller: PhoneListCtrl, 
        resolve: { 
            phones: ["Phone", "$q", function(Phone, $q) {
                var deferred = $q.defer();
                Phone.query(function(successData) {
                  deferred.resolve(successData); 
                }, function(errorData) {
                  deferred.reject(); // you could optionally pass error data here
                });
                return deferred.promise;
             ]
            },
            delay: ["$q","$defer", function($q, $defer) {
               var delay = $q.defer();
               $defer(delay.resolve, 1000);
               return delay.promise;
              }
            ]
        },

        }).
      when('/phones/:phoneId', {
        templateUrl: 'partials/phone-detail.html', 
        controller: PhoneDetailCtrl, 
        resolve: PhoneDetailCtrl.resolve}).
      otherwise({redirectTo: '/phones'});
}]);

angular.controller("PhoneListCtrl", [ "$scope", "phones", ($scope, phones) {
  $scope.phones = phones;
  $scope.orderProp = 'age';
}]);

যেহেতু এই কোডটি প্রশ্ন / সর্বাধিক জনপ্রিয় উত্তর থেকে উদ্ভূত হয়েছে এটি অরীক্ষিত, তবে যদি আপনি ইতিমধ্যে কীভাবে সংশোধন বান্ধব কৌনিক কোড বানাবেন তা বুঝতে পারলে এটি আপনাকে সঠিক দিকে প্রেরণ করা উচিত। আমার নিজের কোডটির যে অংশটি প্রয়োজন ছিল না সেটি হ'ল 'ফোনগুলির' জন্য রেজোলিউশন ফাংশনে একটি "ইনজেকশন" ছিল, না আমি কোনও 'বিলম্ব' বস্তুটি মোটেই ব্যবহার করি নি।

আমি এই ইউটিউব ভিডিওটি http://www.youtube.com/watch?v=P6KITGRQujQ&list=UUKW92i7iQFuNILqQOUOCrFw&index=4&feature=plcp এর প্রস্তাব দিই , যা আমাকে বেশ কিছুটা সহায়তা করেছিল

আপনি কি আমার নিজের কোডটিও পোস্ট করার সিদ্ধান্ত নিয়েছেন তা আগ্রহী হওয়া উচিত (কোফিস্ক্রিপ্টে লিখিত) যাতে আপনি দেখতে পাচ্ছেন যে এটি কীভাবে কাজ করে।

এফওয়াইআই, আগাম আমি জেনেরিক নিয়ামক ব্যবহার করি যা আমাকে বেশ কয়েকটি মডেলের CRUD করতে সহায়তা করে:

appModule.config ['$routeProvider', ($routeProvider) ->
  genericControllers = ["boards","teachers","classrooms","students"]
  for controllerName in genericControllers
    $routeProvider
      .when "/#{controllerName}/",
        action: 'confirmLogin'
        controller: 'GenericController'
        controllerName: controllerName
        templateUrl: "/static/templates/#{controllerName}.html"
        resolve:
          items : ["$q", "$route", "$http", ($q, $route, $http) ->
             deferred = $q.defer()
             controllerName = $route.current.controllerName
             $http(
               method: "GET"
               url: "/api/#{controllerName}/"
             )
             .success (response) ->
               deferred.resolve(response.payload)
             .error (response) ->
               deferred.reject(response.message)

             return deferred.promise
          ]

  $routeProvider
    .otherwise
      redirectTo: '/'
      action: 'checkStatus'
]

appModule.controller "GenericController", ["$scope", "$route", "$http", "$cookies", "items", ($scope, $route, $http, $cookies, items) ->

  $scope.items = items
      #etc ....
    ]

আমি কি আপনার উদাহরণ এবং আমার ব্যর্থ প্রচেষ্টা থেকে সঠিকভাবে অনুমান করি যে কৌণিকের resolveসাম্প্রতিক সংস্করণগুলিতে নিয়ামকের কোনও ক্রিয়াকলাপটি উল্লেখ করা এখন অসম্ভব ? সুতরাং এটি ঠিক এখানে কনফিগার হিসাবে ঘোষণা করতে হবে?
এক্সএমএল

@ এক্সএমলেলি আমি নিশ্চিত যে কেস এই উদাহরণটি 1.1.2 থেকে ছিল যখন আমি এটি লিখেছিলাম, আমি বিশ্বাস করি। কোনও
নিয়ামকের

2
শীতল ধন্যবাদ. এটি করার জন্য প্রচুর উদাহরণ রয়েছে (শীর্ষস্থানীয় দু'জনের মতো এখানে) তবে এগুলি সবই ২০১২ এবং ২০১৩ সালের প্রথম দিকে It's এটি একটি মার্জিত পন্থা, তবে অবচিত বলে মনে হচ্ছে। সবচেয়ে পরিষ্কার বিকল্পটি এখন ব্যক্তিগত পরিষেবাগুলি লেখা বলে মনে হচ্ছে যা প্রতিশ্রুতিবদ্ধ অবজেক্ট।
এক্সএমএল

ধন্যবাদ এটি আমার জন্য কাজ করেছে। অপরিবর্তিত $deferপরিষেবা সম্পর্কে যে কেউ ত্রুটি পেয়েছে তার জন্য , নোট করুন যে AngularJS এর ​​1.5.7 সংস্করণে, আপনি $timeoutপরিবর্তে ব্যবহার করতে চান ।
racl101

18

এই প্রতিশ্রুতিবদ্ধতা , যা সংস্করণ 1.1.5 এবং তারও বেশি অংশের অংশ, এর $promiseঅবজেক্টটি প্রকাশ করে $resource। এই প্রতিশ্রুতি সহ এনজিআরসোর্সের সংস্করণগুলি এই জাতীয় সংস্থানগুলি সমাধান করার অনুমতি দেয়:

$ routeProvider

resolve: {
    data: function(Resource) {
        return Resource.get().$promise;
    }
}

নিয়ামক

app.controller('ResourceCtrl', ['$scope', 'data', function($scope, data) {

    $scope.data = data;

}]);

কোন সংস্করণ যে প্রতিশ্রুতি অন্তর্ভুক্ত, দয়া করে?
এক্সএমএল

সর্বশেষতম অস্থির সংস্করণ (1.1.5) এ প্রতিশ্রুতি অন্তর্ভুক্ত করে। ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js
ম্যাক্সিমিলিয়ান হফম্যান

আমি এই কম ভারবস পদ্ধতির পছন্দ। সত্যিকারের ডেটা অবজেক্ট থেকে কোনও প্রতিশ্রুতি তৈরি করে সরাসরি তা পাস করে দেওয়া ভাল, তবে এটি এত কম কোড যে এটি দুর্দান্তভাবে কাজ করে।
স্যাম বার্নুম

1
কীভাবে সম্পদ অ্যাক্সেস করবে - রুটপ্যারাম? উদাহরণস্বরূপ: ইন GET '/api/1/apps/:appId'-> App.get({id: $routeParams.appId}).$promise();আমি
এটির

2
@ জেরোনোন $routeআপনার সংকল্প এবং ব্যবহারের জন্য ইনজেক্ট করুন $route.current.params। সতর্কতা অবলম্বন করুন, $routeParamsএখনও পুরানো রুটের দিকে ইশারা করছেন।
ব্রাইস স্টেসি

16

এই স্নিপেটটি নির্ভরতা ইনজেকশন বান্ধব (আমি এটি এনজিমন এবং ইউগ্লিফের সংমিশ্রণেও ব্যবহার করি ) এবং এটি আরও মার্জিত চালিত ডোমেন ভিত্তিক সমাধান সমাধান করে।

নীচের উদাহরণটি একটি ফোন সংস্থান এবং একটি ধ্রুবক ফোনরউসগুলি নিবন্ধভুক্ত করে যা এতে (ফোন) ডোমেনের জন্য আপনার সমস্ত রাউটিং তথ্য ধারণ করে। প্রদত্ত উত্তরে আমি যা পছন্দ করি না তা হ'ল সমাধানের যুক্তির অবস্থান - মূল মডিউলটি জানা উচিত নয় কিছু বা নিয়ন্ত্রককে কীভাবে সম্পদ আর্গুমেন্ট সরবরাহ করা হয় সে সম্পর্কে উদ্বিগ্ন । এইভাবে যুক্তি একই ডোমেনে থাকে।

দ্রষ্টব্য: আপনি যদি এনজিমন ব্যবহার করছেন (এবং যদি আপনি না হন তবে: আপনার উচিত) আপনাকে কেবল ডিআই অ্যারে কনভেনশন সহ সমাধান ফাংশনগুলি লিখতে হবে।

angular.module('myApp').factory('Phone',function ($resource) {
  return $resource('/api/phone/:id', {id: '@id'});
}).constant('phoneRoutes', {
    '/phone': {
      templateUrl: 'app/phone/index.tmpl.html',
      controller: 'PhoneIndexController'
    },
    '/phone/create': {
      templateUrl: 'app/phone/edit.tmpl.html',
      controller: 'PhoneEditController',
      resolve: {
        phone: ['$route', 'Phone', function ($route, Phone) {
          return new Phone();
        }]
      }
    },
    '/phone/edit/:id': {
      templateUrl: 'app/phone/edit.tmpl.html',
      controller: 'PhoneEditController',
      resolve: {
        form: ['$route', 'Phone', function ($route, Phone) {
          return Phone.get({ id: $route.current.params.id }).$promise;
        }]
      }
    }
  });

পরবর্তী অংশটি মডিউলটি যখন কনফিগার অবস্থায় থাকে এবং $ রুটপ্রভাইডারে এটি প্রয়োগ করে তখন রাউটিং ডেটা ইনজেকশন করা হয় ।

angular.module('myApp').config(function ($routeProvider, 
                                         phoneRoutes, 
                                         /* ... otherRoutes ... */) {

  $routeProvider.when('/', { templateUrl: 'app/main/index.tmpl.html' });

  // Loop through all paths provided by the injected route data.

  angular.forEach(phoneRoutes, function(routeData, path) {
    $routeProvider.when(path, routeData);
  });

  $routeProvider.otherwise({ redirectTo: '/' });

});

এই সেটআপ দিয়ে রুট কনফিগারেশন পরীক্ষা করাও বেশ সহজ:

describe('phoneRoutes', function() {

  it('should match route configuration', function() {

    module('myApp');

    // Mock the Phone resource
    function PhoneMock() {}
    PhoneMock.get = function() { return {}; };

    module(function($provide) {
      $provide.value('Phone', FormMock);
    });

    inject(function($route, $location, $rootScope, phoneRoutes) {
      angular.forEach(phoneRoutes, function (routeData, path) {

        $location.path(path);
        $rootScope.$digest();

        expect($route.current.templateUrl).toBe(routeData.templateUrl);
        expect($route.current.controller).toBe(routeData.controller);
      });
    });
  });
});

আপনি আমার সর্বশেষ (আসন্ন) পরীক্ষায় এটি পুরো গৌরবতে দেখতে পাবেন । যদিও এই পদ্ধতিটি আমার পক্ষে ভাল কাজ করে, আমি সত্যিই আশ্চর্য হই যে promise ইঞ্জেক্টর যখন কোনও প্রতিশ্রুতিযুক্ত বস্তুর কোনও ইঞ্জেকশন সনাক্ত করে তখন কেন কোনও কিছু নির্মাণে বিলম্ব করছে না ; এটি জিনিসগুলিকে খুব সহজ করে তুলবে।

সম্পাদনা: ব্যবহৃত কৌণিক ভি 1.2 (আরসি 2)


2
এই দুর্দান্ত উত্তরটি "কৌণিক" দর্শনের (এনক্যাপসুলেশন ইত্যাদির) সাথে সামঞ্জস্যপূর্ণ অনেক বেশি মনে হয়। আমাদের সবার উচিত কুডজুর মতো কোডবেজ জুড়ে লজিককে থামানোর জন্য সচেতন প্রচেষ্টা করা।
zakdances

I really wonder why the $injector isn't delaying construction of anything when it detects injection of anything that is a promise objectআমি অনুমান করছি তারা এই কার্যকারিতা বাদ দিয়েছে কারণ এটি নকশার ধরণগুলিকে উত্সাহিত করতে পারে যা অ্যাপ্লিকেশনগুলির প্রতিক্রিয়াটিকে নেতিবাচকভাবে প্রভাবিত করে। তাদের মনের আদর্শ অ্যাপটি হ'ল সত্যই অবিচ্ছিন্ন, সুতরাং সমাধান করা উচিত একটি প্রান্তের কেস।
zakdances

11

রুটটি দেখানোতে বিলম্ব হওয়াকে নিশ্চিত করে একটি অ্যাসিনক্রোনাস জট বাঁধার দিকে ... কেন কেবল আপনার মূল সত্তার লোডিং স্থিতিটি অনুসরণ করা হয় না এবং সেই দৃশ্যটিকে ব্যবহার করে। উদাহরণস্বরূপ আপনার নিয়ামক আপনি এনজিআরসোর্সে সাফল্য এবং ত্রুটি কলব্যাক উভয়ই ব্যবহার করতে পারেন:

$scope.httpStatus = 0; // in progress
$scope.projects = $resource.query('/projects', function() {
    $scope.httpStatus = 200;
  }, function(response) {
    $scope.httpStatus = response.status;
  });

তারপরে দৃষ্টিতে আপনি যা কিছু করতে পারেন:

<div ng-show="httpStatus == 0">
    Loading
</div>
<div ng-show="httpStatus == 200">
    Real stuff
    <div ng-repeat="project in projects">
         ...
    </div>
</div>
<div ng-show="httpStatus >= 400">
    Error, not found, etc. Could distinguish 4xx not found from 
    5xx server error even.
</div>

6
সিএসএস ক্লাস এবং ডিওএম উপাদানগুলি নিয়ামকের অন্তর্ভুক্তের সাথে ডিল করার চেয়ে সম্ভবত এইচটিটিপি স্থিতির দৃষ্টিতে এক্সপোজ করা সঠিক নয়। আমি সম্ভবত একই ধারণাটি ব্যবহার করতে চাই তবে ইসভিড () এবং ইসলয়েড () এ বিমূর্ত স্ট্যাটাসটি দূরে রাখব।
jpsimons

1
এটি প্রকৃতপক্ষে উদ্বেগের সেরা বিভাজন নয়, এবং যদি আপনার নির্দিষ্ট নেটের উপর নির্ভরশীল নেস্টাল নিয়ন্ত্রক থাকে তবে এটি ক্রাশ হবে।
নাল

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

সমস্যাটি যদি কেবল কোনও দৃষ্টিতে দেরি করার বিষয়টি হয়ে থাকে তবে এটি ঠিক থাকবে। তবে সমাধানটি সর্বোত্তমভাবে ব্যবহৃত হয় যদি আপনার কোনও নিয়ামকের ইনস্ট্যান্টেশন বিলম্ব করতে হয় - কেবল দেখার জন্য নয়। (প্রাক্তন: যদি আপনার নিশ্চিত হওয়া দরকার যে আপনার জেএসওএন লোড হয়েছে কারণ আপনার কন্ট্রোলার তারের আগে এটি কোনও নির্দেশিকায় প্রেরণ করে)) ডক্স থেকে: "রাউটারটি তাদের সমস্ত সমাধান হওয়ার জন্য অপেক্ষা করবে বা নিয়ামক হওয়ার আগে একটি প্রত্যাখ্যানিত হবে will তাত্ক্ষণিক "।
ড্যান

8

আমি উপরের মিসকো কোড থেকে কাজ করেছি এবং এটি দিয়ে এটিই করেছি। যেহেতু $deferপরিবর্তিত হয়েছে এটি এটি একটি আরও বর্তমান সমাধান $timeout। বদলে $timeoutঅবশ্য সময়পর্ব জন্য অপেক্ষা করব (Misko এর কোড, 1 সেকেন্ডের মধ্যে) তাহলে প্রত্যাশী এটা সময় এই সমস্যাগুলি সমাধান করা হচ্ছে ডেটা ফিরে যান। এইভাবে, এটি asap ফেরত দেয়।

function PhoneListCtrl($scope, phones) {
  $scope.phones = phones;
  $scope.orderProp = 'age';
}

PhoneListCtrl.resolve = {

  phones: function($q, Phone) {
    var deferred = $q.defer();

    Phone.query(function(phones) {
        deferred.resolve(phones);
    });

    return deferred.promise;
  }
}

7

অ্যাঙ্গুলারজেএস 1.1.5 ব্যবহার করে

অ্যাঙ্গুলারজেএস 1.1.5 ব্যবহার করে জাস্টেনের উত্তরে 'ফোন' ফাংশন আপডেট করা সিনট্যাক্স ।

মূল:

phones: function($q, Phone) {
    var deferred = $q.defer();

    Phone.query(function(phones) {
        deferred.resolve(phones);
    });

    return deferred.promise;
}

আপডেট করা হয়েছে:

phones: function(Phone) {
    return Phone.query().$promise;
}

কৌণিক দল এবং অবদানকারীদের জন্য খুব ছোট ধন্যবাদ thanks :)

এটি ম্যাক্সিমিলিয়ান হফম্যানেরও উত্তর। স্পষ্টতই সেই প্রতিশ্রুতি এটি 1.1.5 এ তৈরি করেছে।


1
আমি কিছু খুঁজে মনে করতে পারে না $promiseডক্স । এটি v2.0 + হিসাবে নেওয়া হয়েছে।
জাকদানস

এটি কেবলমাত্র 1.2 তে পাওয়া যায়
টমাস

5

আপনি ডেটা লোড না হওয়া অবধি রুট পরিবর্তন বিলম্ব করতে $ রুটপ্রভাইডার রেজোলিউশন সম্পত্তিটি ব্যবহার করতে পারেন ।

angular.module('app', ['ngRoute']).
  config(['$routeProvider', function($routeProvider, EntitiesCtrlResolve, EntityCtrlResolve) {
    $routeProvider.
      when('/entities', {
        templateUrl: 'entities.html', 
        controller: 'EntitiesCtrl', 
        resolve: EntitiesCtrlResolve
      }).
      when('/entity/:entityId', {
        templateUrl: 'entity.html', 
        controller: 'EntityCtrl', 
        resolve: EntityCtrlResolve
      }).
      otherwise({redirectTo: '/entities'});
}]);

লক্ষ করুন যে resolveসম্পত্তিটি রুটে সংজ্ঞায়িত করা হয়েছে।

EntitiesCtrlResolveএবং EntityCtrlResolveহয় ধ্রুবক হিসাবে একই ফাইলের মধ্যে নির্ধারণ বস্তু EntitiesCtrlএবং EntityCtrlকন্ট্রোলার।

// EntitiesCtrl.js

angular.module('app').constant('EntitiesCtrlResolve', {
  Entities: function(EntitiesService) {
    return EntitiesService.getAll();
  }
});

angular.module('app').controller('EntitiesCtrl', function(Entities) {
  $scope.entities = Entities;

  // some code..
});

// EntityCtrl.js

angular.module('app').constant('EntityCtrlResolve', {
  Entity: function($route, EntitiesService) {
    return EntitiesService.getById($route.current.params.projectId);
  }
});

angular.module('app').controller('EntityCtrl', function(Entity) {
  $scope.entity = Entity;

  // some code..
});

3

আমি ডার্কপোর্টারের ধারণা পছন্দ করি কারণ অ্যাংুলারজেএস-এ নতুন কোনও দেব দলের পক্ষে বুঝতে এবং সরাসরি কাজ করা সহজ হবে।

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

$ সুযোগে একটি 'প্রস্তুত' পতাকা যুক্ত করুন:

$http({method: 'GET', url: '...'}).
    success(function(data, status, headers, config) {
        $scope.dataForView = data;      
        $scope.ready = true;  // <-- set true after loaded
    })
});

এইচটিএমএল ভিউতে:

<div ng-show="!ready">

    <!-- Show loading graphic, e.g. Twitter Boostrap progress bar -->
    <div class="progress progress-striped active">
        <div class="bar" style="width: 100%;"></div>
    </div>

</div>

<div ng-show="ready">

    <!-- Real content goes here and will appear after loading -->

</div>

আরও দেখুন: বুস্ট্র্যাপ অগ্রগতি বার ডক্স


যদি আপনি একাধিক ডেটা লোড করে থাকেন তবে কিছুটা আলাদা হয়ে যায়। আপনি কীভাবে জানবেন যে সবকিছু লোড হয়েছে?
toxaq

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

আমি কিছুটা দেরি করে পৌঁছেছি, তবে একাধিক ডেটা টুকরো নিয়ে ডিল করা বড় উদ্বেগের নয়। আপনাকে প্রতিটি অনুরোধের জন্য পৃথক ভেরিয়েবলগুলি (বুলেটিয়ানস: isReadyData1, isReadyData2 ইত্যাদি) ব্যবহার করতে হবে এবং and সুযোগ.ডিডি = isReadyData1 && isReadyData2 ... সেট করতে হবে; আমার জন্য ভাল কাজ করে।
গিলাইমএ

1

আমি উপরের উত্তরগুলি পছন্দ করেছি এবং সেগুলি থেকে অনেক কিছু শিখেছি তবে উপরের উত্তরগুলির মধ্যে বেশিরভাগটি অনুপস্থিত রয়েছে।

আমি অনুরূপ দৃশ্যে আটকে ছিলাম যেখানে আমি সার্ভারের প্রথম অনুরোধে প্রাপ্ত কিছু ডেটা দিয়ে url সমাধান করছিলাম res সমস্যাটির মুখোমুখি হয়েছি যদি প্রতিশ্রুতি দেওয়া হয় rejected

আমি যা ফিরতে ব্যবহৃত একটি কাস্টম প্রদানকারী ব্যবহার করছিলেন Promiseযার দ্বারা মুকুব করা হয়েছে resolveএর$routeProvider কনফিগ পর্যায়ের সময়ে।

আমি এখানে চাপ দিতে চাই কি ধারণা when এরকম কিছু করে।

এটি ইউআরএল বারে ইউআরএল দেখতে পায় এবং তারপরে whenনিয়ন্ত্রক হিসাবে সম্পর্কিত ব্লক এবং ভিউ এত ভাল বলে উল্লেখ করা হয়।

আসুন বলুন যে আমার কাছে কনফিগার ফেজ কোড রয়েছে।

App.when('/', {
   templateUrl: '/assets/campaigns/index.html',
   controller: 'CampaignListCtr',
   resolve : {
      Auth : function(){
         return AuthServiceProvider.auth('campaign');
      }
   }
})
// Default route
.otherwise({
   redirectTo: '/segments'
});

ব্রাউজারের রুট ইউআরএল এ প্রথমে রানের ব্লক ডেকে আনা হয় অন্যথায় otherwiseফোন করা হয়।

আসুন ভাবুন যাক অ্যাড্রেস বার ফাংশনটিতে আমি রুটআরলকে হিট করেছি AuthServicePrivider.auth()called

বলুন প্রতিশ্রুতি ফিরে এসেছে রাষ্ট্রের প্রত্যাখ্যান হয় তবে কি ???

কিছুই রেন্ডার হয় না।

Otherwise ব্লক কার্যকর করা হবে না কারণ এটি কোনও ইউআরএল যা কনফিগার ব্লকে সংজ্ঞায়িত নয় এবং কৌনিক জে কনফিগার পর্যায়ে অজানা।

এই প্রতিশ্রুতি মীমাংসিত না হলে আমাদের যে ইভেন্টটি বরখাস্ত হয়ে যায় পরিচালনা করতে হবে। ব্যর্থতায়$routeChangeErorr বরখাস্ত হয়$rootScope

এটি নীচের কোডে প্রদর্শিত হিসাবে ক্যাপচার করা যেতে পারে।

$rootScope.$on('$routeChangeError', function(event, current, previous, rejection){
    // Use params in redirection logic.
    // event is the routeChangeEvent
    // current is the current url
    // previous is the previous url
    $location.path($rootScope.rootPath);
});

আইএমও সাধারণত অ্যাপ্লিকেশনটির ব্লক ইভেন্ট ইভেন্ট ট্র্যাকিং কোড রাখা ভাল ধারণা। এই কোডটি অ্যাপ্লিকেশনটির কনফিগার পর্যায়ের ঠিক পরে চলে।

App.run(['$routeParams', '$rootScope', '$location', function($routeParams, $rootScope, $location){
   $rootScope.rootPath = "my custom path";
   // Event to listen to all the routeChangeErrors raised
   // by the resolve in config part of application
   $rootScope.$on('$routeChangeError', function(event, current, previous, rejection){
       // I am redirecting to rootPath I have set above.
       $location.path($rootScope.rootPath);
   });
}]);

এইভাবে আমরা কনফিগার পর্যায়ে সময় প্রতিশ্রুতি ব্যর্থতা পরিচালনা করতে পারি।


0

অক্ষম স্ক্রিন স্তর সহ আমার একটি জটিল মাল্টি-লেভেল স্লাইডিং প্যানেল ইন্টারফেস রয়েছে। অক্ষম করা স্ক্রিন স্তর সম্পর্কিত নির্দেশনা তৈরি করা যা এই জাতীয় অবস্থা কার্যকর করতে ক্লিক ইভেন্ট তৈরি করে

$state.go('account.stream.social.view');

একটি চটজলদি প্রভাব উত্পাদন করা হয়। ইতিহাস.ব্যাক () এর পরিবর্তে এটি ঠিকঠাক কাজ করেছে, তবে এটি আমার ক্ষেত্রে ইতিহাসে সর্বদা ফিরে আসে না। সুতরাং আমি যা জানতে পারি তা হল যদি আমি কেবল state.go এর পরিবর্তে আমার অক্ষম স্ক্রিনে অ্যাট্রিবিউট href তৈরি করি তবে একটি কবজির মতো কাজ করে।

<a class="disable-screen" back></a>

নির্দেশ 'পিছনে'

app.directive('back', [ '$rootScope', function($rootScope) {

    return {
        restrict : 'A',
        link : function(scope, element, attrs) {
            element.attr('href', $rootScope.previousState.replace(/\./gi, '/'));
        }
    };

} ]);

app.js আমি কেবল পূর্বের অবস্থাটি সংরক্ষণ করি

app.run(function($rootScope, $state) {      

    $rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) {         

        $rootScope.previousState = fromState.name;
        $rootScope.currentState = toState.name;


    });
});

-2

একটি সম্ভাব্য সমাধান হ'ল আমরা মডেলগুলি উদাহরণস্বরূপ ব্যবহার করছি এমন উপাদানটির সাথে এনজি-ক্লোকার নির্দেশকে ব্যবহার করা

<div ng-cloak="">
  Value in  myModel is: {{myModel}}
</div>

আমি মনে করি এটির জন্য কম প্রচেষ্টা করা দরকার takes

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