1

Update: I ended up using properties that access the model and call the external change tracking inside the setters.

get text(): string { 
    return model.text
}
set text(value: string) {
    // <-- Call the change tracker here
    this.model.text = value;
}

Original Question

I have a system written using AngularJS where I needed to externally track the changes of each model (track dirties). In AngularJS it was a simple as adding watchers for every model's property (including changes in properties of elements inside arrays). Note: the models are used as the data for the UI components.

The data flow was like this:

  1. SPA requests data from server.
  2. Server gets the data.
  3. A watcher is added to every model's property before returning the data.
  4. Watched models are returned to the SPA.

Here's the main code that watched for changes:

public attachModel(obj : any, id : string, scope: ng.IScope, propertyName: string) {
    var idObj = obj.Id;
    this.attachedObjs[obj.Id] = obj; // Just keeping control of tracked objs
    var that = this;
    // The 'id' used in the watch is unique for the tracked property
    scope.$watch(id, function () {
        that.changeTracker(idObj, propertyName); // Calls dirty tracking
    });
}

Every time a property was changed in any of the models, an event was triggered and the model's property was marked as dirty in the external change control.

I am trying to find a replacement for this functionality in the new Angular, but I feel like I am not in the right path, the only options that I currently have are:

  • Use something like RxJS Do method to call the dirty tracking.
  • Use ngrx Observables and add @Effects to trigger the dirty tracking.

One important thing is that in AngularJS I had a single point where all models were added to dirty tracking control.

Is there any way to achieve this in Angular? Or a way to intercept Angular's Change Detection to trigger the dirty tracking?

Note: I found a question that somehow I missed during my initial search, is there any way to achieve this outside an ngForm? How to watch for form changes in Angular 2?

Oscar Vasquez
  • 391
  • 7
  • 16
  • can you post code for that part `A watcher is added to every model before returning the data.` and that `Every time a property was changed in any of the models, an event was triggered and the model's property was marked as dirty in the external change control.`? – Max Koretskyi Jul 13 '17 at 16:55
  • @Maximus I added the sample code. – Oscar Vasquez Jul 13 '17 at 17:35
  • you wrote `Triggers dirty tracking`, but a watcher callback is executed inside the digest. what does the function `changeTracker` do? also where this code is placed? in a directive? it has access to the scope, what scope is it? – Max Koretskyi Jul 13 '17 at 17:46
  • @Maximus (updated to `Calls dirty tracking`) that just adds it to an object that contains all the modified properties, this will be sent on each `submit` and cleaned up after is sent. – Oscar Vasquez Jul 13 '17 at 17:50
  • sorry, still too many details, try narrowing the question – Max Koretskyi Jul 13 '17 at 17:52

1 Answers1

2

If the model you want to track is a form input in an angular form you can listen the valueChanges stream.

LookForAngular
  • 1,030
  • 8
  • 18
  • The models are used as the data for UI components, like grids, textbox, drop-downs, etc. Is this valueChanges stream still applicable? – Oscar Vasquez Jul 13 '17 at 16:52
  • The rule can be applied yo any abstract control which is implemented by form controls and form groups – LookForAngular Jul 13 '17 at 16:57
  • Thanks! Looking for the valueChanges I found this other question https://stackoverflow.com/questions/34615425/how-to-watch-for-form-changes-in-angular-2 it has very useful information. – Oscar Vasquez Jul 13 '17 at 18:31