66 * found in the LICENSE file at https://angular.io/license
77 */
88
9+ import { bindingUpdated } from '../bindings' ;
910import { SanitizerFn } from '../interfaces/sanitization' ;
11+ import { RENDERER } from '../interfaces/view' ;
12+ import { isSignal } from '../reactivity/api' ;
13+ import { isWritableSignal } from '../reactivity/signal' ;
14+ import { getCurrentTNode , getLView , getSelectedTNode , getTView , nextBindingIndex } from '../state' ;
1015
11- import { ɵɵlistener } from './listener' ;
12- import { ɵɵproperty } from './property ' ;
16+ import { listenerInternal } from './listener' ;
17+ import { elementPropertyInternal , storePropertyBindingMetadata } from './shared ' ;
1318
1419
1520/**
@@ -27,8 +32,21 @@ import {ɵɵproperty} from './property';
2732 */
2833export function ɵɵtwoWayProperty < T > (
2934 propName : string , value : T , sanitizer ?: SanitizerFn | null ) : typeof ɵɵtwoWayProperty {
30- // TODO(crisbeto): implement two-way specific logic.
31- ɵɵproperty ( propName , value , sanitizer ) ;
35+ // TODO(crisbeto): perf impact of re-evaluating this on each change detection?
36+ if ( isSignal ( value ) ) {
37+ value = value ( ) as T ;
38+ }
39+
40+ const lView = getLView ( ) ;
41+ const bindingIndex = nextBindingIndex ( ) ;
42+ if ( bindingUpdated ( lView , bindingIndex , value ) ) {
43+ const tView = getTView ( ) ;
44+ const tNode = getSelectedTNode ( ) ;
45+ elementPropertyInternal (
46+ tView , tNode , lView , propName , value , lView [ RENDERER ] , sanitizer , false ) ;
47+ ngDevMode && storePropertyBindingMetadata ( tView . data , tNode , propName , bindingIndex ) ;
48+ }
49+
3250 return ɵɵtwoWayProperty ;
3351}
3452
@@ -41,8 +59,9 @@ export function ɵɵtwoWayProperty<T>(
4159 * @codeGenApi
4260 */
4361export function ɵɵtwoWayBindingSet < T > ( target : unknown , value : T ) : boolean {
44- // TODO(crisbeto): implement this fully.
45- return false ;
62+ const canWrite = isWritableSignal ( target ) ;
63+ canWrite && target . set ( value ) ;
64+ return canWrite ;
4665}
4766
4867/**
@@ -55,6 +74,9 @@ export function ɵɵtwoWayBindingSet<T>(target: unknown, value: T): boolean {
5574 */
5675export function ɵɵtwoWayListener (
5776 eventName : string , listenerFn : ( e ?: any ) => any ) : typeof ɵɵtwoWayListener {
58- ɵɵlistener ( eventName , listenerFn ) ;
77+ const lView = getLView < { } | null > ( ) ;
78+ const tView = getTView ( ) ;
79+ const tNode = getCurrentTNode ( ) ! ;
80+ listenerInternal ( tView , lView , lView [ RENDERER ] , tNode , eventName , listenerFn ) ;
5981 return ɵɵtwoWayListener ;
6082}
0 commit comments