4

I am trying to extend 3rd party component with some custom functionality by wrapping it into custom component.

But I am having issues with property binding - how do I create two-way property bind between parent, wrapper, and 3rd party component? (A chained-two-way bind property :)

So simplified html template would look like this

wrapper-component.html
<someCompotentToExtend [(ngModel)]="wrapProperty"></someCompotentToExtend>
}

wrapper-component.ts
export class WrapperComponent{
   wrapProperty:string=""
}

and in parent component i would do something like this

parent-component.html
<wrapper-component [(wrapProperty)]="parentProperty"></<wrapper-component>

parent-component.ts
export class ParentComponent{
   parentProperty:string=""
}

Changing any of these properties should update all other binded properties?

I ran a bunch of the test, i came close to solutions in these two examples but its too hacky and not working properly in the end

First solution

Using @Input @Output in wrapper component or on model change event. Wrapper component has a intermediary property, for example, wrapProperty which is bind to 3d party component or listening for changes. This will kindaaa work. In my case it is not what I want because after wrapper updates parent, parent will update wrapper component :??? :)

export class WrappedComponentComponent {
  wrapProperty:string=""

  @Input() set propertyFromParent(value: string) {    
    this.wrapProperty= value;
  }
  @Output() propertyFromParentChange= new EventEmitter();

Second solution

Using this framework ngx-context. It is really cool, creates a temporary local provider service through which you can share data. But it requires additional syntax when calling wrapper component and I need something that is more encapsulate.

It it possible to create a chained two-way binding system of properties? Thank you, any help is appreciated

djulb
  • 375
  • 1
  • 3
  • 19
  • How about using a SharedService? – SiddAjmera Dec 21 '19 at 11:47
  • So basically the question is if I have component with 2 way binding then how to create wrapper component over it which will also have 2 way binding with wrapped component, right? – Plochie Dec 21 '19 at 12:08
  • Yes exactly that. Binding two components using a wrapper component. Where updating property of one component will update other two. The reason why i dont use shared service - I need to make that component encapsulated. Just specify property and that is it. And just as a sidenote, parent component can have multiple wrapped components. – djulb Dec 21 '19 at 12:34
  • 1
    I am not sure, but how about passing property wrapped in another object :). like: [(wrapProperty)]="{ data: parentProperty }", then in the wrapper you can use: [(ngModel)]="wrapProperty['data']". I have not tested it, but I think it might solve it (but yeah it is messy). – Mohammad Hassany Dec 21 '19 at 12:43
  • 1
    Why cant you get output event from parent, then update the wrapper and vice versa for input? – Plochie Dec 21 '19 at 13:41
  • Yes, you were correct with using Input and output. I initially was trying to use that mechanics but it was receiving an extra on update event which was messing up stuff for me. Anyway I added an answer to this question. Thank you – djulb Dec 26 '19 at 07:43

1 Answers1

2

Here is a working solution https://stackblitz.com/edit/angular-di6px5?file=app%2Fform.component.ts

I accidentally made an error and used [(ngModel)] instead of separating them into [ngModel] and (ngModelChange). Separating allowed to have a better control of properties and avoid that extra update event i was receiving.

djulb
  • 375
  • 1
  • 3
  • 19