เปลี่ยนเส้นทางสถานะไปยังวัสดุรองเริ่มต้นด้วย UI-Router ใน AngularJS


89

ฉันกำลังสร้างหน้าตามแท็บซึ่งแสดงข้อมูลบางอย่าง ฉันใช้ UI-Router ใน AngularJs เพื่อลงทะเบียนสถานะ

เป้าหมายของฉันคือการเปิดแท็บเริ่มต้นหนึ่งแท็บในการโหลดหน้าเว็บ แต่ละแท็บมีแท็บย่อยและฉันต้องการเปิดแท็บย่อยเริ่มต้นเมื่อเปลี่ยนแท็บ

ฉันกำลังทดสอบด้วยonEnterฟังก์ชั่นและข้างในฉันใช้$state.go('mainstate.substate');แต่ดูเหมือนว่าจะไม่ทำงานเนื่องจากปัญหาผลกระทบของลูป (ใน state.go เพื่อแทนที่มันเรียกสถานะแม่และอื่น ๆ และมันจะกลายเป็นลูป)

$stateProvider

.state('main', {
  url: '/main',
  templateUrl: 'main.html',
  onEnter: function($state) {
    $state.go('main.street');
  }
})

.state('main.street', {
  url: '/street',
  templateUrl: 'submenu.html',
  params: {tabName: 'street'}
})

นี่ฉันสร้างสาธิต plunker

ตอนนี้ทุกอย่างใช้งานได้ยกเว้นฉันไม่ได้เปิดแท็บเริ่มต้นและนั่นคือสิ่งที่ฉันต้องการ

ขอบคุณสำหรับข้อเสนอแนะความคิดเห็นและแนวคิด

คำตอบ:


172

อัปเดต: 1.0 เป็นต้นไปรองรับการเปลี่ยนเส้นทางเพื่อออกจากกล่อง

https://ui-router.github.io/ng1/docs/latest/interfaces/state.statedeclaration.html#redirectto


ฉันสร้างตัวอย่างที่นี่ตัวอย่างที่นี่

วิธีแก้ปัญหานี้มาจาก "ความคิดเห็น" ที่ดีไปจนถึงปัญหาเกี่ยวกับการเปลี่ยนเส้นทางโดยใช้.when() ( https://stackoverflow.com/a/27131114/1679310 )และวิธีแก้ปัญหาที่ยอดเยี่ยมมาก(โดย Chris T แต่โพสต์ต้นฉบับโดย yahyaKacem)

https://github.com/angular-ui/ui-router/issues/1584#issuecomment-75137373

ก่อนอื่นมาขยาย main ด้วยการตั้งค่าการเปลี่ยนเส้นทาง:

$stateProvider
    .state('main', {
      url: '/main',
      templateUrl: 'main.html',
      redirectTo: 'main.street',
    })

และเพิ่มเพียงไม่กี่บรรทัดนี้ในการเรียกใช้

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

    $rootScope.$on('$stateChangeStart', function(evt, to, params) {
      if (to.redirectTo) {
        evt.preventDefault();
        $state.go(to.redirectTo, params, {location: 'replace'})
      }
    });
}]);

ด้วยวิธีนี้เราสามารถปรับสถานะของเราด้วยการเปลี่ยนเส้นทางเริ่มต้น ... ตรวจสอบได้ที่นี่

แก้ไข: เพิ่มตัวเลือกจากความคิดเห็นโดย @Alec เพื่อรักษาประวัติเบราว์เซอร์


4
สิ่งนี้ดูเหมือนจะทำให้ยุ่งเหยิงปุ่มย้อนกลับ
Scott Sword

6
@ Swordfish0321 เพื่อแก้ไขปุ่มย้อนกลับทำการเปลี่ยนแปลงเล็กน้อยนี้: $state.go(to.redirectTo, params, {location: 'replace'});สิ่งนี้จะทำให้สถานะใหม่แทนที่สถานะก่อนหน้า (เช่นสถานะที่เราถูกเปลี่ยนเส้นทาง) ในประวัติศาสตร์ ดูเอกสารสำหรับ $ state.go: angular-ui.github.io/ui-router/site/#/api/…
Alec

2
แค่อยากจะเพิ่มเติมว่านี่ใกล้เคียงกับสิ่งที่ฉันต้องการทำจริงๆ แต่ฉันต้องการ URL เริ่มต้นแทนที่จะแทนที่มันสามารถทำได้อย่างง่ายดายโดยเปลี่ยน'$stateChangeStart'เป็น'$stateChangeSuccess'
Matti Price

6
ui-router 1.0 ได้สร้างไว้รองรับสิ่งนี้: ui-router.github.io/guide/ng1/…
เกิร์ต -

21

ในความเป็นจริงแม้ว่าโซลูชันนี้ที่เสนอโดยRadimจะทำงานได้ดี แต่ฉันก็ต้องจำแท็บย่อย (สถานะ) ของทุกแท็บ

ดังนั้นฉันจึงพบวิธีแก้ปัญหาอื่นที่ทำสิ่งเดียวกัน แต่ยังจำทุกแท็บย่อยด้วย

สิ่งที่ฉันต้องทำคือติดตั้งui-router-extrasและใช้คุณสมบัติdeep state redirect :

$stateProvider
  .state('main.street', {
     url: '/main/street',
     templateUrl: 'main.html',
     deepStateRedirect: { default: { state: 'main.street.cloud' } },
  });

ขอขอบคุณ!



7

นับตั้งแต่ ui-router เวอร์ชัน 1.0 เป็นต้นมามีการนำ hook เริ่มต้นโดยใช้IHookRegistry.onBefore ()ตามที่แสดงในตัวอย่างData Driven Default Substateในhttp://angular-ui.github.io/ui-router/feature-1.0/ อินเทอร์เฟซ / การเปลี่ยนแปลง ihookregistry.html # onbefore

// state declaration
{
  name: 'home',
  template: '<div ui-view/>',
  defaultSubstate: 'home.dashboard'
}

var criteria = {
  to: function(state) {
    return state.defaultSubstate != null;
  }
}
$transitions.onBefore(criteria, function($transition$, $state) {
  return $state.target($transition$.to().defaultSubstate);
});

งานประเภทนี้สำหรับฉันแม้ว่าฉันจะต้องปรับแต่ง (ใช้ ES6 ด้วย)$transitions.onBefore({ to: state => state.defaultSubstate != null }, trans => trans.router.stateService.target(trans.to().defaultSubstate));

3
app.config(function($stateProvider,$urlRouterProvider){

    $urlRouterProvider.when("/state","/state/sub-state");

    })

1
คุณช่วยให้คำอธิบายได้ไหมว่าสิ่งนี้ทำอะไรและทำไมถึงดีกว่าคำตอบที่มีอยู่แล้ว
Equalsk

วิธีนี้เป็นวิธีที่ง่ายที่สุดและได้ผลดีสำหรับฉัน
BuffMcBigHuge

นี่คือคำตอบที่ดีที่สุด กระชับกว่าการใช้เหตุการณ์การเปลี่ยนแปลง ไม่ต้องเพิ่มแพ็คเกจ ฉันไม่รู้ว่ามันไม่ชัดเจนสำหรับใคร ฉันไม่รู้ว่าคำตอบที่ได้รับการยอมรับนั้นได้รับการโหวตมากแค่ไหน
CodeWarrior

1

หากมีคนมาที่นี่เพื่อขอคำตอบเกี่ยวกับวิธีใช้การเปลี่ยนเส้นทางอย่างง่ายสำหรับสถานะและอย่างที่เกิดขึ้นกับฉันไม่มีโอกาสใช้เราเตอร์ใหม่ ...

แน่นอนอีกครั้งถ้าคุณทำได้คำตอบ @bblackwo นั้นยอดเยี่ยม:

$stateProvider.state('A', {
  redirectTo: 'B',
});

หากคุณไม่สามารถเปลี่ยนเส้นทางได้ด้วยตนเอง:

$stateProvider.state('A', {
  controller: $state => {
    $state.go('B');
  },
});

ฉันหวังว่ามันจะช่วยได้!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.