কৌণিক জেএস ইউআই রাউটার - পুনরায় লোড অবস্থায় ছাড়াই url পরিবর্তন করুন


134

বর্তমানে আমাদের প্রকল্পটি ডিফল্ট ব্যবহার করছে $routeProviderএবং urlপৃষ্ঠাটি পুনরায় লোড না করে পরিবর্তন করতে আমি এই "হ্যাক" ব্যবহার করছি :

services.service('$locationEx', ['$location', '$route', '$rootScope', function($location, $route, $rootScope) {
    $location.skipReload = function () {
        var lastRoute = $route.current;
        var un = $rootScope.$on('$locationChangeSuccess', function () {
            $route.current = lastRoute;
            un();
        });
        return $location;
    };
    return $location;
}]);

এবং ভিতরে controller

$locationEx.skipReload().path("/category/" + $scope.model.id).replace();

আমি নীড়ের রুটের routeProviderসাথে প্রতিস্থাপনের কথা ভাবছি ui-router, তবে এটি খুঁজে পাচ্ছি না ui-router

এটা কি সম্ভব - সঙ্গে একই কি angular-ui-router?

আমার কেন এটি দরকার? একটি উদাহরণ দিয়ে আমাকে ব্যাখ্যা করতে দাও:
নতুন বিভাগ তৈরির জন্য রুটটি আমি দেখাব সেভ করার /category/new পরে এবং আমি রুটটি পরিবর্তন করতে চাই (23 - ডিবিতে সঞ্চিত নতুন আইটেমের আইডি)clickingsuccess-alert/category/new/caterogy/23


1
ইউআই-রাউটারে আপনাকে প্রতিটি রাজ্যের জন্য একটি ইউআরএল সংজ্ঞায়িত করতে হবে না, আপনি ইউআরএল পরিবর্তন না করেই একটি রাজ্য থেকে রাজ্যে নেভিগেট করতে পারবেন
জোনাথন ডি এম

আপনি কি পুরো URL টি আপডেট করতে চান বা কেবল অনুসন্ধানের পথটি? আমি অনুসন্ধানের পথটি আপডেট করার মতো একটি সমাধান অনুসন্ধান করছিলাম এবং এটি এখানে পেয়েছি: stackoverflow.com/questions/21425378/…
ফ্লোরিয়ান লচ

@ জোহনাথন সত্যি? আমি এটি করতে পছন্দ করব, কেবলমাত্র একটি একক ইউআরএল দেখিয়ে, তবে $urlRouterProvider.otherwiseমনে হয় কোনও ইউআরএল, কোনও রাজ্যে নয় operate হুম, সম্ভবত আমি 2 টি ইউআরএল নিয়ে থাকতে পারি বা এটি একটি অবৈধ ইউআরএল তা বোঝানোর জন্য অন্য কোনও উপায় খুঁজে পেতে পারি।
মাওগ বলছেন মনিকা

উত্তর:


164

কেবল আপনি $state.transitionTo পরিবর্তে ব্যবহার করতে পারেন $state.go । অভ্যন্তরীণভাবে $state.go কল $state.transitionTo করে কিন্তু স্বয়ংক্রিয়ভাবে বিকল্পগুলি সেট করে { location: true, inherit: true, relative: $state.$current, notify: true } । আপনি কল $state.transitionTo এবং সেট করতে পারেন notify: false । উদাহরণ স্বরূপ:

$state.go('.detail', {id: newId}) 

দ্বারা প্রতিস্থাপন করা যেতে পারে

$state.transitionTo('.detail', {id: newId}, {
    location: true,
    inherit: true,
    relative: $state.$current,
    notify: false
})

সম্পাদনা করুন: fracz দ্বারা প্রস্তাবিত হিসাবে এটি সহজভাবে হতে পারে:

$state.go('.detail', {id: newId}, {notify: false}) 

16
"অবস্থা পুনরায় লোড না করে url পরিবর্তন করুন" এর পরিবর্তে "স্থিতি পুনরায় লোড করার সময় ইউআরএল রাখুন"?
পিটার হেডবার্গ

25
আমার জন্য এটি নিম্নলিখিতগুলির সাথে কাজ করেছে: $state.transitionTo('.detail', {id: newId}, { location: true, inherit: true, relative: $state.$current, notify: false }) সুতরাং মূলত মিথ্যা এবং অবস্থানটিকে সত্য হিসাবে অবহিত করুন
আরজেন ডি ভ্রিজ

6
@ আর্জেন্টিভিস হ্যাঁ এটি প্রত্যাশা অনুযায়ী কাজ করছে তবে আমি একটি অপ্রত্যাশিত আচরণ পেয়েছি। অনেকগুলি ট্রানজিশন টো মেথড কল (পুনরায় লোড না করে) সাথে খেলার পরে আপনি যখন শেষ পর্যন্ত একটি নতুন অবস্থায় চলে যান (যেমন। ইউআরএল), এটি পুরানো নিয়ামকটিকে পুনরায় আরম্ভ করে।
প্রেমচন্দ্র সিং

2
@ প্রমচন্দ্র সিং: এখানেও একই বিষয় রয়েছে। রাজ্যটি ছাড়ার সময়, পুরানো নিয়ামকটি আবার আরম্ভ হয়। উইহেরেক থেকে গৃহীত সমাধানের সাথে আমি একই সমস্যা পেয়েছি। আরও দেখুন এখানে github.com/angular-ui/ui-router/issues/64
মার্টিনোস

15
এমনকি সহজ: $state.go('.detail', {id: newId}, {notify: false})
fracz

48

ঠিক আছে, সমাধান করা হয়েছে: কৌণিক ইউআই রাউটারের এই নতুন পদ্ধতি রয়েছে, $ urlRouterProvider.deferIntercept () https://github.com/angular-ui/ui-router/issues/64

মূলত এটি এখানে আসে:

angular.module('myApp', [ui.router])
  .config(['$urlRouterProvider', function ($urlRouterProvider) {
    $urlRouterProvider.deferIntercept();
  }])
  // then define the interception
  .run(['$rootScope', '$urlRouter', '$location', '$state', function ($rootScope, $urlRouter, $location, $state) {
    $rootScope.$on('$locationChangeSuccess', function(e, newUrl, oldUrl) {
      // Prevent $urlRouter's default handler from firing
      e.preventDefault();

      /** 
       * provide conditions on when to 
       * sync change in $location.path() with state reload.
       * I use $location and $state as examples, but
       * You can do any logic
       * before syncing OR stop syncing all together.
       */

      if ($state.current.name !== 'main.exampleState' || newUrl === 'http://some.url' || oldUrl !=='https://another.url') {
        // your stuff
        $urlRouter.sync();
      } else {
        // don't sync
      }
    });
    // Configures $urlRouter's listener *after* your custom listener
    $urlRouter.listen();
  }]);

আমি মনে করি এই পদ্ধতিটি বর্তমানে কেবলমাত্র কৌনিক ইউআই রাউটারের মাস্টার সংস্করণে অন্তর্ভুক্ত রয়েছে, এটি alচ্ছিক পরামিতিগুলির সাথে রয়েছে (যা খুব সুন্দর, বিটিডাব্লু)। এটি উত্স থেকে ক্লোন করা এবং তৈরি করা প্রয়োজন

grunt build

দস্তাবেজগুলি উত্স থেকেও অ্যাক্সেসযোগ্য

grunt ngdocs

(এগুলি / সাইট ডিরেক্টরিতে নির্মিত হয়) // README.MD তে আরও তথ্য

গতিশীল পরামিতি (যা আমি ব্যবহার করি নি) দ্বারা এটি করার আরও একটি উপায় রয়েছে বলে মনে হয় । অনেক ক্রেডিট নটবেলে।


সিডনোট হিসাবে, এখানে কৌনিক ইউআই রাউটারের $ স্টেটপ্রোভাইডারটিতে alচ্ছিক পরামিতি রয়েছে, যা আমি উপরের সাথে সংমিশ্রণে ব্যবহার করেছি:

angular.module('myApp').config(['$stateProvider', function ($stateProvider) {    

  $stateProvider
    .state('main.doorsList', {
      url: 'doors',
      controller: DoorsListCtrl,
      resolve: DoorsListCtrl.resolve,
      templateUrl: '/modules/doors/doors-list.html'
    })
    .state('main.doorsSingle', {
      url: 'doors/:doorsSingle/:doorsDetail',
      params: {
        // as of today, it was unclear how to define a required parameter (more below)
        doorsSingle: {value: null},
        doorsDetail: {value: null}
      },
      controller: DoorsSingleCtrl,
      resolve: DoorsSingleCtrl.resolve,
      templateUrl: '/modules/doors/doors-single.html'
    });

}]);

এটি কী করে তা প্যারামগুলির মধ্যে একটি অনুপস্থিত থাকলেও কোনও রাষ্ট্রের সমাধান করতে দেয়। এসইও একটি উদ্দেশ্য, পাঠযোগ্যতা অন্য।

উপরের উদাহরণে, আমি চেয়েছিলাম দরজা সিঙ্গেল একটি প্রয়োজনীয় প্যারামিটার হোক। সেগুলি কীভাবে সংজ্ঞায়িত করা যায় তা পরিষ্কার নয়। যদিও এটি একাধিক alচ্ছিক পরামিতিগুলির সাথে ঠিক আছে, তাই আসলে সমস্যা নয়। আলোচনাটি এখানে https://github.com/angular-ui/ui-router/pull/1032#issuecomment-49196090


দেখে মনে হচ্ছে আপনার alচ্ছিক পরামিতিগুলি কাজ করে না। Error: Both params and url specicified in state 'state'। এটি ডক্সে বলেছে যে এটিও অবৈধ ব্যবহার। কিছুটা হতাশার।
Rhys ভ্যান ডার ওয়েয়ারডেন

1
আপনি মাস্টার থেকে তৈরি করেছেন? দয়া করে নোট করুন যে আমি যখন সমাধানটি যুক্ত করেছি তখন alচ্ছিক পরামিতিগুলি কেবলমাত্র সেই সংস্করণে অন্তর্ভুক্ত ছিল যা উত্স থেকে ম্যানুয়ালি তৈরি করতে হয়েছিল। v.0.3 শেষ না হওয়া পর্যন্ত এটি প্রকাশে অন্তর্ভুক্ত করা হবে না।
wiherek

1
শুধু একটি দ্রুত নোট। নাতাবেলের জন্য ধন্যবাদ vচ্ছিক প্যারামিটারগুলি v0.2.11 এ পাওয়া যায় যা কিছুদিন আগে প্রকাশিত হয়েছিল।
rich97

এটি অত্যন্ত বিভ্রান্তিকর: আমি কীভাবে ব্যবহার করব $ urlRouterProvider.deferIntercept (); যাতে আমি নিয়ামকটি আবার লোড না করে প্যারামগুলি আপডেট করতে পারি? এটি আমাকে সত্যিই তা দেখায় না। রান ফাংশনটির মধ্যে আপনি সিঙ্ক বা সিঙ্ক না করার জন্য যদি একটি বিবৃতি মূল্যায়ন করতে পারেন তবে আমাকে যা করতে হবে তা হ'ল পুরানো এবং নতুন ইউআরএল। আমি কীভাবে জানতে পারি যে এটি এমন একটি উদাহরণ যেখানে আমি যা করতে চাই তা হল কেবলমাত্র দুটি url দিয়ে কাজ করার জন্য আপডেট করা? যুক্তিটি কি .... (যদি পুরানো রাষ্ট্র এবং নতুন রাষ্ট্র একই হয় তবে নিয়ামকটি আবার লোড করবেন না?) আমি বিভ্রান্ত।
বিটিএম 1

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

16

এই সমস্যাটি নিয়ে অনেক সময় ব্যয় করার পরে, আমি যা কাজ করেছি তা এখানে

$state.go('stateName',params,{
    // prevent the events onStart and onSuccess from firing
    notify:false,
    // prevent reload of the current state
    reload:false, 
    // replace the last record when changing the params so you don't hit the back button and get old params
    location:'replace', 
    // inherit the current params on the url
    inherit:true
});

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

@ আইজয় মূলত প্রশ্নটি কেবলমাত্র জিজ্ঞাসা করা হয়েছে ui-router, আপনি কীভাবে বলতে পারেন যে অন্যান্য সমাধানগুলি কাজ করে যাচ্ছিল $routerProvider, $routeProviderএবং $stateProviderস্থাপত্যের ক্ষেত্রে সম্পূর্ণ আলাদা ছিল ..
পঙ্কজ পার্কার

আমরা যদি পিছনের বোতামটি এটি দিয়ে কাজ করতে না চাই তবে কী হবে? মানে, পিছনের প্রেসে আগের অবস্থায় / ইউআরএল যেতে হবে, বিভিন্ন
প্যারামের

আমার ধারণা, এই সমাধানের মাধ্যমে ব্রাউজারটি কাজ করবে না, কারণ আমরা কোনও রাজ্যে ইউআই-রাউটারকে না জানিয়ে পরিবর্তন করছি
পঙ্কজ পার্কার

2
আমি এটি চেষ্টা করেছি এবং দেখে মনে হচ্ছে $onInit()যে প্রতিবার আমি যখন ব্যবহার করি তখন আমার উপাদানটিতে ডাকা হয় $state.go। আমার কাছে 100% ঠিক আছে বলে মনে হচ্ছে না।
Carm

8

কল করা হচ্ছে

$state.go($state.current, {myParam: newValue}, {notify: false});

এখনও নিয়ামক পুনরায় লোড করবে।

এড়াতে, আপনাকে প্যারামিটারটি ডায়নামিক হিসাবে ঘোষণা করতে হবে:

$stateProvider.state({
    name: 'myState',
    url: '/my_state?myParam',
    params: {
        myParam: {
          dynamic: true,
        }
    },
    ...
});

তারপরে আপনার এমনকি এমনকি notifyকল করার দরকার নেই

$state.go($state.current, {myParam: newValue})

আল্লাহই যথেষ্ট। Neato!

ডকুমেন্টেশন থেকে :

কখন dynamicহয়true , প্যারামিটার মানতে পরিবর্তনগুলি রাষ্ট্রকে প্রবেশ / প্রস্থান করার কারণ করে না। সমাধানগুলি পুনরায় ফিরিয়ে আনা হবে না, আবার দৃশ্যগুলি পুনরায় লোড করা হবে না।

[...]

এটি ইউআই তৈরিতে কার্যকর হতে পারে যেখানে প্যারামের মানগুলি পরিবর্তিত হয় যখন উপাদানটি নিজেই আপডেট হয়।


7

এই সেটআপটি আমার জন্য নিম্নলিখিত সমস্যার সমাধান করেছে:

  • ইউআরএল আপডেট করার সময় প্রশিক্ষণ নিয়ামককে দুবার কল করা হয় না .../ করতে.../123
  • প্রশিক্ষণ নিয়ামক অন্য রাজ্যে নেভিগেট করার সময় পুনরায় চাওয়া হয় না

রাষ্ট্রের কনফিগারেশন

state('training', {
    abstract: true,
    url: '/training',
    templateUrl: 'partials/training.html',
    controller: 'TrainingController'
}).
state('training.edit', {
    url: '/:trainingId'
}).
state('training.new', {
    url: '/{trainingId}',
    // Optional Parameter
    params: {
        trainingId: null
    }
})

রাজ্যগুলি চালনা করা (অন্য কোনও নিয়ামক থেকে)

$scope.editTraining = function (training) {
    $state.go('training.edit', { trainingId: training.id });
};

$scope.newTraining = function () {
    $state.go('training.new', { });
};

প্রশিক্ষণ নিয়ামক

var newTraining;

if (!!!$state.params.trainingId) {

    // new      

    newTraining = // create new training ...

    // Update the URL without reloading the controller
    $state.go('training.edit',
        {
            trainingId : newTraining.id
        },
        {
            location: 'replace', //  update url and replace
            inherit: false,
            notify: false
        });     

} else {

    // edit

    // load existing training ...
}   

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

এটি আমার পক্ষে কাজ করেছে এবং এটি এখন পর্যন্ত সবচেয়ে সুস্পষ্ট সমাধান
ওডেলিলি

3

আপনার যদি কেবল ইউআরএল পরিবর্তন প্রয়োজন তবে পরিবর্তিত রাষ্ট্রটি প্রতিরোধ করুন:

এর সাথে অবস্থান পরিবর্তন করুন (আপনি যদি ইতিহাসে প্রতিস্থাপন করতে চান তবে পুনরায় স্থান যোগ করুন):

this.$location.path([Your path]).replace();

আপনার রাজ্যে পুনঃনির্দেশ প্রতিরোধ করুন:

$transitions.onBefore({}, function($transition$) {
 if ($transition$.$to().name === '[state name]') {
   return false;
 }
});

2

আমি এটি করেছি তবে অনেক আগে সংস্করণে: ইউআই-রাউটারের v0.2.10 এর মতো কিছু ::

$stateProvider
  .state(
    'home', {
      url: '/home',
      views: {
        '': {
          templateUrl: Url.resolveTemplateUrl('shared/partial/main.html'),
          controller: 'mainCtrl'
        },
      }
    })
  .state('home.login', {
    url: '/login',
    templateUrl: Url.resolveTemplateUrl('authentication/partial/login.html'),
    controller: 'authenticationCtrl'
  })
  .state('home.logout', {
    url: '/logout/:state',
    controller: 'authenticationCtrl'
  })
  .state('home.reservationChart', {
    url: '/reservations/?vw',
    views: {
      '': {
        templateUrl: Url.resolveTemplateUrl('reservationChart/partial/reservationChartContainer.html'),
        controller: 'reservationChartCtrl',
        reloadOnSearch: false
      },
      'viewVoucher@home.reservationChart': {
        templateUrl: Url.resolveTemplateUrl('voucher/partial/viewVoucherContainer.html'),
        controller: 'viewVoucherCtrl',
        reloadOnSearch: false
      },
      'addEditVoucher@home.reservationChart': {
        templateUrl: Url.resolveTemplateUrl('voucher/partial/voucherContainer.html'),
        controller: 'voucherCtrl',
        reloadOnSearch: false
      }
    },
    reloadOnSearch: false
  })


-6

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

সুতরাং, এই বিষয়টি মাথায় রেখে, কেন নীচের মতো কিছু দিয়ে $ লোকেশন.পাথকে (পদ্ধতিটি একজন গেটর এবং সেটার উভয় হিসাবে) কেবল পরিবর্তন করবেন না:

var newPath = IdFromService;
$location.path(newPath);

ডকুমেন্টেশন নোট পথ সবসময় একটা ফরওয়ার্ড স্ল্যাশ দিয়ে শুরু করা উচিত যে, কিন্তু এই যোগ করা হবে তা অনুপস্থিত।


আমি যখন ব্যবহার করি ui-routerএবং ব্যবহার করি $location.path(URL_PATH), পৃষ্ঠাটি স্বয়ংক্রিয়ভাবে পুনরায় রেন্ডার হয় ?!
কাউশা

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