2016-03-03 17 views
6

Tôi không thể tìm ra cách hiển thị hộp thoại tùy chỉnh thay vì sử dụng số window.confirm thông thường routeWillLeavehistory.listenBefore sử dụng. Về cơ bản tôi đã xây dựng một hệ thống thông báo và kiểm tra xem biểu mẫu có bị bẩn không const { dispatch, history, dirty } = this.props;Hiển thị hộp thoại tùy chỉnhRouteLeaveHook hoặc history.listenTrước khi phản ứng-bộ định tuyến/redux?

nếu biểu mẫu bị bẩn nghĩa là người dùng chưa lưu thay đổi. Nếu họ thay đổi tuyến đường, tôi muốn hiển thị thông báo của tôi sẽ có hai nút STAY, IGNORE, cả hai đều có thể xử lý onClick.

Tôi đã dành một chút thời gian googling và havent đi qua bất kỳ đề cập đến cách tôi có thể thực hiện điều này bằng cách sử dụng routeWillLeave. Điều gần nhất tôi có thể tìm thấy là sử dụng history.listenBefore tuy nhiên có tài liệu nói rằng tôi cần phải làm điều này.

let history = createHistory({ 
    getUserConfirmation(message, callback) { 
    callback(window.confirm(message)) // The default behavior 
    } 
}) 

Nhưng tôi đang sử dụng browserHistory từ phản ứng-router để bắt đầu cửa hàng của tôi const history = syncHistoryWithStore(browserHistory, store);

Làm thế nào tôi có thể ngăn chặn một sự thay đổi tuyến đường sau khi một liên kết được nhấp, hiển thị một thông báo sử dụng hệ thống thông báo tùy chỉnh của tôi và tùy thuộc vào nút nào được nhấp vào chuyển đổi sang tuyến đường mới hoặc ở lại? Dưới đây là một ví dụ về cách thức hoạt động của hệ thống thông báo của tôi và hướng ive đi vào mà rõ ràng là không hoạt động vì tất cả các trả về này là một chuỗi để hiển thị trong cửa sổ dialog.confirm theo mặc định.

history.listenBefore((location) => { 
    if(this.props.dirty){ 
    const acceptBtn = { 
     title: 'STAY', 
     handler: ignoreRouteChange() //This can be any function I want 
    } 
    const denyBtn = { 
     title: 'IGNORE', 
     handler: continueRouteChange() //This can be any function I want 
    } 
    return dispatch(addNotification({ 
     message: 'You have unsaved changes!', 
     type: NOTIFICATION_TYPE_WARNING, 
     duration: 0, 
     canDismiss: false, 
     acceptBtn, 
     denyBtn 
    })); 
    return "Usaved changes!" 
    } 
}); 

Cảm ơn

+1

Tôi vừa trả lời một câu hỏi tương tự ở đây: http://stackoverflow.com/a/35793421/52041 –

+0

Cảm ơn vì điều đó, chỉ vì tò mò bạn đã nghĩ ra giải pháp đó như thế nào? Bạn đã nghiên cứu cách setRouterLeaveHook được triển khai và triển khai lại nó để cung cấp phiên bản asynv hay ..? – Deep

+0

Không, tôi chỉ làm một chút động não với một đồng nghiệp, dựa trên hành vi của setRouterLeaveHook. –

Trả lời

0

Một giải pháp mà tôi đã quyết định sử dụng là để trả về false trong callback setRouterLeaveHook bình thường và sau đó hiển thị hộp thoại của tôi và sử dụng nextLocation truyền cho gọi lại để đẩy các tuyến đường tiếp theo tùy thuộc vào nút lựa chọn.

router.setRouteLeaveHook(route, this.routerWillLeave.bind(this)); 

routerWillLeave(nextLocation){ 
    let { dirty, dispatch, resetForm } = this.props; 
    if (dirty) { 
    let dialog = { 
     id: Date.now(), 
     showTitle: true, 
     titleContent: 'Unsaved Changes', 
     titleIcon: 'fa fa-warning', 
     content: <span>You have <strong>unsaved</strong> changes! <strong>Discard</strong> them?</span>, 
     type: 'confirm', 
     handleCloseClick: (e) => { 
     e.preventDefault(); 
     dispatch(closeDialog()); 
     }, 
     acceptBtn: { 
     title: 'Okay', 
     handler: (e) => { 
      e.preventDefault(); 
      resetForm(); 
      // Wait for call stack to unwind and then execute 
      // the following which will now have the updated values. 
      setTimeout(() => { 
      dispatch(push(nextLocation)); 
      dispatch(closeDialog()); 
      }, 0); 
     } 
     }, 
     denyBtn: { 
     title: 'Deny', 
     handler: (e) => { 
      e.preventDefault(); 
      dispatch(closeDialog()); 
     } 
     } 
    } 
    dispatch(addDialogWindow(dialog)); 
    dispatch(openDialog(false, (e) => dispatch(closeDialog()), false)); 
    return false; 
    } 
    return true; 
} 
+0

Bất kỳ ý tưởng nào tại sao đạo cụ không được cập nhật mà không sử dụng 'setTimeout'? – Yuri

+0

Trong trường hợp người dùng đang cố điều hướng bằng cách sử dụng nút quay lại của trình duyệt, điều này sẽ không hoạt động một cách kỳ lạ -> Mã của bạn sẽ đẩy vị trí mới vào lịch sử thay vì quay lại lịch sử? – nzjoel

Các vấn đề liên quan