Legion
Legion

Reputation: 3457

Updating entire model object in angular

I have an object called eventData that is a singleton that is injected into multiple controllers via a resolve.

eventData contains both view data like drop down list values as well as my model. Basically it looks like this:

eventData.DropDownListValues1
eventData.DropDownListValues2
eventData.MyModel

Then in each of my controllers I have this:

angular.module('myWebApp.controllers').
    controller('MyCtrl', function ($scope, eventData, coreAPIservice, ViewMatrixService, UtilityService) {

        $scope.myModel = eventData.MyModel;
        $scope.dropDownListValues1 = eventData.DropDownListValues1;
});

And my views look like:

<select class="form-control input-sm"
        ng-model="myModel.Item"
        ng-options="myItem as myItem.ItemName for myItem in dropDownList1 track by myItem.ItemId">
    <option value="" selected disabled hidden>Select Item...</option>
</select>

After a post my webservice returns the updated model that now contains IDs generated by the database. I tried reassigning over eventData.MyModel but it doesn't cause all the controllers referencing MyModel to update.

coreAPIservice.UpdateEvent(eventData.MyModel).success(function (response) {
    eventData.MyModel = response;
});

Normally when I update a property of the model from any controller like this:

$scope.myModel.myProperty1 = "abcdefg";

That property change is immediately reflected across all controllers/views that reference eventData.MyModel.

My guess is that because I'm replacing the entire MyModel object the reference is being lost and therefore the views don't update.

The only options I can think of are re-fetching the data after a post or updating each property individually.

I don't like re-fetching because it's redundant. I already have the updated model from the post. Adding another fetch just slows things down and amounts to a page refresh.

I don't like updating each property individually since there are over 1000 properties on MyModel and it would take a while to code and not be very performant.

Upvotes: 2

Views: 132

Answers (1)

Igor
Igor

Reputation: 62308

Change your controller constructor code like this:

$scope.eventData= eventData;
Object.defineProperty($scope, "myModel", { get: function () { return $scope.eventData.MyModel; } });
Object.defineProperty($scope, "dropDownListValues1", { get: function () { return $scope.eventData.DropDownListValues1; } });

What this does is register myModel as property (not a field) on the $scope. The property then always retrieves the MyModel object from the eventData when referenced. This will allow you to keep your existing HTML as is. It will also allow you to update the entire model on your EventData instance without having to push events through. Your controller will have a reference (as a field) to EventData but you do not have to reference that with the exception of in the created getter property.

You might want to double check my JavaScript syntax, I got it from here

Upvotes: 1

Related Questions