Trong một ứng dụng nhỏ tôi xây dựng có sử dụng thuốc thử và Re-frame Tôi đang sử dụng đa phương để gửi trang nào sẽ được hiển thị dựa trên một giá trị trong tình trạng ứng dụng:Tại sao đa phương pháp không hoạt động như chức năng cho Thuốc thử/Tái khung?
(defmulti pages :name)
(defn main-panel []
(let [current-route (re-frame/subscribe [:current-route])]
(fn []
;...
(pages @current-route))))
và sau đó tôi có các phương pháp như:
(defmethod layout/pages :register [_] [register-page])
nơi register-page
chức năng sẽ tạo ra cái nhìn thực tế:
(defn register-page []
(let [registration-form (re-frame/subscribe [:registration-form])]
(fn []
[:div
[:h1 "Register"]
;...
])))
tôi đã cố gắng changing my app so that the methods generated the pages directly, như trong:
(defmethod layout/pages :register [_]
(let [registration-form (re-frame/subscribe [:registration-form])]
(fn []
[:div
[:h1 "Register"]
;...
])))
và điều đó không làm cho trang không bao giờ được hiển thị. Trong bảng điều khiển chính của tôi, tôi changed the call to pages
to square brackets nên thuốc thử mà có thể có tầm nhìn vào nó:
(defn main-panel []
(let [current-route (re-frame/subscribe [:current-route])]
(fn []
;...
[pages @current-route])))
và khiến trang thăm đầu tiên để làm việc, nhưng sau đó, nhấp vào liên kết (gây vãng lộ trình để thay đổi) không có hiệu ứng.
Tất cả các không gian tên xác định các phương thức riêng lẻ được yêu cầu trong tệp được tải trước, chứa hàm init và thực tế là tôi có thể chọn bất kỳ trang nào và hiển thị mã chứng minh đang tải (sau đó, chuyển đổi đến một trang khác không hoạt động):
https://github.com/carouselapps/ninjatools/blob/master/src/cljs/ninjatools/core.cljs#L8-L12
Trong một nỗ lực để gỡ lỗi những gì đang xảy ra, tôi đã xác định hai tuyến đường, :about
và :about2
, một như một chức năng và một như một phương pháp:
(defn about-page []
(fn []
[:div "This is the About Page."]))
(defmethod layout/pages :about [_]
[about-page])
(defmethod layout/pages :about2 [_]
(fn []
[:div "This is the About 2 Page."]))
và thực hiện bố cục in kết quả gọi pages
(đã phải sử dụng cuộc gọi rõ ràng thay vì dấu ngoặc vuông của khóa học). Các chức năng bao bọc, một trong đó hoạt động, trả về:
[#object[ninjatools$pages$about_page "function ninjatools$pages$about_page(){
return (function(){
return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"div","div",1057191632),"This is the About Page."], null);
});
}"]]
trong khi phương thức trả về:
#object[Function "function(){
return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"div","div",1057191632),"This is the About 2 Page."], null);
}"]
Nếu tôi thay đổi phương pháp là:
(defmethod layout/pages :about2 [_]
[(fn []
[:div "This is the About 2 Page."])])
có nghĩa là, trả lại trong một vector, sau đó, nó bắt đầu hoạt động. Và nếu tôi thực hiện thay đổi ngược lại với chức năng bao bọc, nó bắt đầu thất bại trong việc theo cách tương tự như phương pháp:
(defn about-page []
(fn []
[:div "This is the About Page."]))
(defmethod layout/pages :about [_]
about-page)
Làm cho một chút cảm giác như cú pháp thuốc thử là [function]
nhưng nó được cho là để gọi hàm tự động .
Tôi cũng bắt đầu xuất ra @current-route
cho trình duyệt, như trong:
[:main.container
[alerts/view]
[pages @current-route]
[:div (pr-str @current-route)]]
và tôi xác nhận @current-route
đang được sửa đổi một cách chính xác và đầu ra được cập nhật, chỉ cần không [pages @current-route]
.
Mã nguồn đầy đủ cho ứng dụng của tôi có thể được tìm thấy ở đây: https://github.com/carouselapps/ninjatools/tree/multi-methods
Update: corrected the arity of the methods following Michał Marczyk's answer.
Bạn có yêu cầu không gian tên nơi bạn sử dụng 'defmethod' trong một số không gian tên gốc không? Bởi vì nếu bạn không yêu cầu các không gian tên đó một cách rõ ràng, các phương thức của bạn đơn giản là không được thêm vào multimethod. – skrat
@skrat yes. Tôi sẽ chỉnh sửa câu hỏi để lưu ý điều đó. – Pablo
Để gỡ lỗi này tôi sẽ 1. Thêm một phương pháp mặc định và 2. in ra những gì multimethod đang trở về (có lẽ là nil). – PeakCode