-
-
Notifications
You must be signed in to change notification settings - Fork 717
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Signal projection #3695
Comments
EDIT up front: After I'd written the below, I re-read to make sure I was understanding correctly. I think there may be some underlying misunderstanding here. You write:
This means, for example, that they want to be able to call This will return a signal that clones the data exactly once when they call let child_signal = Signal::derive(move || parent_signal.read().data.clone()); This does not store the value anywhere, it is just a boxed closure. Your proposal for a projected signal would be the same: when they called You can do this with a #[derive(Store, Debug)]
struct MyStruct {
data: Vec<usize>,
}
#[component]
pub fn App() -> impl IntoView {
let parent = Store::new(MyStruct { data: vec![] });
view! {
<TakesProjected data=parent.data()/>
}
}
#[component]
pub fn TakesProjected(#[prop(into)] data: Field<Vec<usize>>) -> impl IntoView {
todo!()
} For what it's worth, you can also do the "projected signal" version in user-land (i.e., you can create a nicer API for it than the example below). This kind of approach is kind of a manual store, but is enabled by the same primitives. I think this is not worth it in most cases, but it does give you the level of control you'd need. #[derive(Debug)]
struct MyStruct {
data: Vec<usize>,
}
#[component]
pub fn App() -> impl IntoView {
let parent_signal = RwSignal::new(MyStruct { data: vec![] });
let projected = move || guards::Mapped::new_with_guard(parent_signal.read(), |s| &s.data);
view! {
<TakesSignalField data=projected />
}
}
#[component]
pub fn TakesSignalField<T>(data: impl Fn() -> T) -> impl IntoView
where
T: Deref<Target = Vec<usize>>,
{
todo!()
} |
Context
I have a wrapper struct, for example:
Then, I have a (third party) component that wants a
Signal<Vec<usize>>
.I want to be able to create a signal that provides
parent_signal.read().data
without unnecessary cloning.Current way of doing it
Currently, one could create the appropriate signal as follows. However, this clones the Vec everytime the child signal is read. This can probably be improved by using memoization, but the vec will still need to be cloned on the first access.
Describe the solution you'd like
I think implementing something like the following could be great (if at all possible):
child_signal.get()
would still clone the value, butchild_signal.read()
would not.This may not be sound for all the types of signals, but I think it does make sense for the regular
ReadSignal
andRwSignal
.The text was updated successfully, but these errors were encountered: