neridaj
neridaj

Reputation: 2193

Angular JS - $watch changes made in directive from controller

I'm trying to $watch changes that happen in directive scope and add objects to an array if they have been changed. The edit functionality is in the directive scope but the save functionality is outside of the directive scope i.e., save is called from controller scope. I'm using a shared object to with two way binding to access the objects that have been edited in the directive scope. The edits are being saved correctly but I need to filter out any objects that have not been changed. I don't understand why the changes aren't reflected in $watch.

// controller

vm.accessor = {};
getGlobalConfigs();
$scope.$watch('vm.accessor.globalConfigs', function(newValue, oldValue) {
    console.log('config changed');
});
function getGlobalConfigs() {
    vehicleConfigurationsFactory.getGlobalConfigs()
    .then(function (data) {
        vm.accessor.globalConfigs = data;
    });
}

// directive

(function(){
'use strict';

angular.module('vehicleConfigurationsModule')
.directive('globalConfig', globalConfig);

    function globalConfig() {

    var directive = {
        link: link,
        replace: false,
        templateUrl: 'app/vehicle-configurations/global-config-tr.html',
        scope: {
          confkey: '@',
          confvalue: '=',
          confprecedence: '=',
          confdescription: '=',
          accessor: '='
        }
    }

    return directive;

    function link(scope, el, attrs, controller) {
      scope.master = {
        confvalue: scope.confvalue,
        confprecedence: scope.confprecedence,
        confdescription: scope.confdescription
      };
      scope.disabled = true;
      scope.precedenceOptions = [
        {value: "GLOBAL"},
        {value: "VEHICLE"}
      ];
      scope.selectedOption = {value: scope.confprecedence};
      scope.edit = function() {
        scope.disabled = false;
        scope.accessor.disabled = false;
      };
      scope.cancel = function() {
        scope.disabled = true;
        scope.accessor.disabled = true;
        scope.confvalue = scope.master.confvalue;
        scope.confprecedence = scope.master.confprecedence;
        scope.confdescription = scope.master.confdescription;
      };
      scope.setPrecedence = function(value) {
        scope.confprecedence = value;
      };
    }

 }


})();

// directive instance

<tr ng-repeat="config in vm.accessor.globalConfigs" global-config confkey="{{ config.confKey }}" confvalue="config.confValue" confprecedence="config.precedence" confdescription="config.description" accessor="vm.accessor"></tr>

// directive template

<td ng-model="config.confKey">{{ confkey }}</td>
<td>
    <input type="text" class="form-control" ng-model="confvalue" ng-disabled="disabled">
</td>
<td>
    <select class="form-control" ng-options="option.value for option in precedenceOptions track by option.value"
ng-model="selectedOption" ng-disabled="disabled" ng-change="setPrecedence(selectedOption.value)"></select>
</td>
<td>
    <input type="text" class="form-control" ng-model="confdescription" ng-disabled="disabled">
</td>
<td>
    <a ng-show="disabled" role="button" translate="{{ 'vehicle-configurations.edit' }}" ng-click="edit()"></a>
    <a ng-show="!disabled" role="button" translate="{{ 'vehicle-configurations.cancel' }}" ng-click="cancel()"></a>
</td>

Upvotes: 0

Views: 1415

Answers (1)

Scott
Scott

Reputation: 1690

This seems like kind of an odd way to do this, however I think you just need to tell your watch to watch the objects INSIDE globalConfigs like this:

$scope.$watch('vm.accessor.globalConfigs', function(newValue, oldValue) {
     console.log('config changed');
},true);

Note the third param to $watch ",true" which tells watch to "deep watch".

Upvotes: 2

Related Questions