Monitoring variable change done by jQuery inside component

95 views Asked by At

I know this isn't optimal, but I have regular javascript code changing a variable that is property in my component.

The reason for this is that I have dynamic javascript (that comes from Google Blockly) being run (eval) in my component.

Here's the component template:

<input #textInput
   [attr.max-value]="maxValue"
   type="number"
   style="width: 495px;"
   (change)="onChange($event)"
   [id]="key"
   class="form-control"
   [disabled]="disabled"
   value="{{value}}" />

And the component code:

export class NumberStepComponent extends BaseStepComponent {
    /** number-step ctor */
    constructor() {
        super();
    }

    @ViewChild("textInput") textInput: ElementRef;

    private _maxValue: string;
    get maxValue(): string {
        return this._maxValue;
    }

    set maxValue(val: string) {
        this._maxValue = val;
        console.log("Changed ** : " + val);
    }

}

When I change maxValue from Angular, I do get the setter code triggered. But when jQuery does it, that setter isn't triggered.

ie:

var code = `$('#ID').attr('max-value', "5")`;
eval(code);

I've tried executing the code "in the zone" thinking this would keep Angular up to date:

this.ngZone.run(() => {
    var code = `$('#ID').attr('max-value', "5")`;
    eval(code);
});

Doesn't trigger the setter either. Any ways to achieve this ?

2

There are 2 answers

0
lovis91 On

It's hard to guess what you can/cannot do but you can try to add a MutationObserver. For example :

const node = document.querySelector('.some-element') // or this.textInput.nativeElement;

const observer = new MutationObserver((mutations) => {
  mutations.forEach((mutation) => console.log(mutation));
});

observer.observe(node, {
  attributes: true,
  childList: true,
  characterData: true
});
3
Random On

You should not use $('#ID').attr('max-value', "5"), since the value is binded (so handled by Angular).

If you want to change the value, update the model (this.maxValue = '5'), not the view. Angular will update the view for you.