Comments (10)
I'm going to steal this issue and refocus it a bit. transform
support isn't necessary to address the problem you're talking about. If we had a way to declare that model()
will emit a narrower type than it accepts, then it could support two-way binding to a WritableSignal<number>
since Signal<number>
is assignable to Signal<number|string>
and we'd never try to write a string
back.
from angular.
This is a duplicate of #55166 which has the previous discussion (which concluded that model()
should not support transform
).
from angular.
I'm going to steal this issue and refocus it a bit.
transform
support isn't necessary to address the problem you're talking about. If we had a way to declare thatmodel()
will emit a narrower type than it accepts, then it could support two-way binding to aWritableSignal<number>
sinceSignal<number>
is assignable toSignal<number|string>
and we'd never try to write astring
back.
But how would you transform the string to the number for input values? At the end the component internally only want number and will always emit number. Only the outside can provide strings.
from angular.
But how would you transform the string to the number for input values? At the end the component internally only want number and will always emit number. Only the outside can provide strings.
You can use a computed
to go from number|string
to just number
.
from angular.
But how would you transform the string to the number for input values? At the end the component internally only want number and will always emit number. Only the outside can provide strings.
You can use a
computed
to go fromnumber|string
to justnumber
.
But wouldn't something like model(2, {inputTansform: fn})
makes more sense? Especially if we look at it as input and output - a model built from input with transform and output with actual type. The output type must be assigned to the input type.
from angular.
@alxhub Just adding that using input and output we can do:
value = input(2, { transform: fn });
valueChange = output<number>();
The only downside is we can't change it from inside and the outside must implement the output and input or two way binding.
Hence the suggested:
value = model(2, {inputTansform: fn});
Which does exactly the same but with model added features.
from angular.
After some discussion, we've decided that it's not really feasible to implement this feature.
One, we (still) don't want to add transform
to model
. The intention of the model
input is that it offers synchronization between the parent component and the model, and that synchronization breaks if a one-way transformation is introduced. This could be interrupted
Narrowing the setter type wouldn't work, as it would break the assignability of model
inputs to the WritableSignal
interface which has no such restrictions.
Given that both options produce tradeoffs that we don't feel strike the right balance, we don't think a change here makes sense.
from angular.
@alxhub so how do you suggest to implement it instead? Using input and output requires the consumer to use two way binding for it to work (btw isn't it the same as what was suggested here but without internal control?)
from angular.
Falling back to input
& output
is I think is a good workaround.
// Input with transform: signal of the internal value.
state = input(..., {transform: ...}); // InputSignal<Wide, Narrow>
// Output side of the two-way binding contract.
stateChange = output<Narrow>();
// Computed to project new input values to a WritableSignal, allowing internal mutations.
stateMutable = computed(() => signal(this.state())); // Signal<WritableSignal<Narrow>>;
// Actual value to use internally (unwrap the nested WritableSignal).
stateInternal = computed(() => this.stateMutable()()); // Signal<Narrow>
// Helper method to update the state (equivalent of `model.set()`).
setState(value: Narrow): void {
this.stateMutable().set(value);
this.stateChange(value);
}
from angular.
Falling back to
input
&output
is I think is a good workaround.// Input with transform: signal of the internal value. state = input(..., {transform: ...}); // InputSignal<Wide, Narrow> // Output side of the two-way binding contract. stateChange = output<Narrow>(); // Computed to project new input values to a WritableSignal, allowing internal mutations. stateMutable = computed(() => signal(this.state())); // Signal<WritableSignal<Narrow>>; // Actual value to use internally (unwrap the nested WritableSignal). stateInternal = computed(() => this.stateMutable()()); // Signal<Narrow> // Helper method to update the state (equivalent of `model.set()`). setState(value: Narrow): void { this.stateMutable().set(value); this.stateChange(value); }
Thanks that's helpful! Just a shame that such a pattern can't be integrated in angular for easier implementation. Especially if there are multiple of those inputs. Models are such a clean way to do it.
I guess one can create a wrapper so it ends up with: input,output,internal wrapper
from angular.
Related Issues (20)
- Not possible to update Angular verrsion globally and locally HOT 2
- Angular DevTools: Could not serialize injector. v18.0.2 HOT 1
- Possible out of context statement regarding base href in Angular Routing Guide
- Former "Control Flow" page does not correctly redirect to new Angular.dev site HOT 1
- Disabling UIkit tootltips using preventDefault throws undefined error in browser on every mouseover element with tooltip HOT 3
- Page not found in documentation on Vite HOT 3
- Infinite money glitch HOT 1
- Update docs to add context on how invalid HTML breaks hydration and how to detect it automatically HOT 1
- Diagram does not match description HOT 3
- ERROR Error: ASSERTION ERROR: Expecting LContainer [Expected=> null !== null <=Actual] HOT 3
- Angular.dev is missing a lot of information HOT 1
- Not able to view https://angular.dev/tools/cli/esbuild HOT 2
- Missing https://angular.dev/errors/NG0913 site HOT 1
- Directive composition: Composed directive should be able to set inputs of constituent directives HOT 4
- Angular compilation failing after migrating to V16 HOT 5
- https://angular.dev/api/localize/init/$localize HOT 2
- `effect()` should have an option to run outside of an injection context HOT 3
- adev: API should show the alias of inputs and outputs
- While migrations the - angular version 8 to 10 I am facing the issue HOT 2
- Error link reported by ag HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from angular.