GeoffreyHervet
GeoffreyHervet

Reputation: 288

Why my value is not updated in the directive's view

I have a value named $scope.title in my controller. This value is initialized with $scope.title = 'global.loading';. I have a factory named Product.

My view is calling a directive via <menu-top ng-title="title"></menu-top>, the view of this directive is <span>{{title|translate}}</span>.

When I want to get a product I do : Product.get(id). Their is two possibility.

First one (working) -> My product is cached in localstorage and my title in the directive is uptated.

Second one (not working) -> My product is not cached, I call my WebService, put the response in cache and return the response. In this case, the title is updated (console.log) in the controller, but not in my directive ...

angular.module('angularApp')
  .directive('menuTop', function () {
    return {
      templateUrl: 'views/directives/menutop.html',
      restrict: 'E',
      scope:{
        ngTitle: '=?'
      },
      link: function postLink(scope) {
        scope.title = scope.ngTitle;
      }
    };
  });



angular.module('angularApp')
  .controller('ProductCtrl', function ($scope, $routeParams, Product) {
    $scope.productId  = parseInt($routeParams.product);
    $scope.title      = 'global.loading';

    $scope.loading  = true;
    $scope.error    = false;
    $scope.product  = null;

    Product
      .get($scope.productId)
      .then(function(product){
        $scope.loading  = false;
        $scope.title = product.name;
        $scope.product = product;
      }, function(){
        $scope.error = true;
        $scope.loading = false;
      })
    ;
  });


angular.module('angularApp')
  .factory('Product', function ($http, responseHandler, ApiLink, LocalStorage, $q) {
    var _get = function(id) {
      return $q(function(resolve, reject) {
        var key = 'catalog/product/' + id;
        var ret = LocalStorage.getObject(key);
        if (ret) {
          return resolve(ret);
        }

        responseHandler
          .handle($http({
            method: 'GET',
            url: ApiLink.get('catalog', 'product', {id: id})
          }))
          .then(function(response) {
            if (response.product && response.product.name) {
              LocalStorage.putObject(key, response.product, 60 * 5);
              return resolve(response.product);
            }
            reject(null);
          }, function() {
            reject(null);
          });
      });
    };

    return {
      'get': _get
    };
  });

Thank you for your help !

Upvotes: 0

Views: 498

Answers (1)

Okazari
Okazari

Reputation: 4597

As Sergio Tulentsev suggested, you can use '@' as binding method.

Using @ will interpolate the value. It means that you can use it as a readonly this way : ng-title="{{mytitle}}"

angular.module('angularApp')
  .directive('menuTop', function () {
    return {
      templateUrl: 'views/directives/menutop.html',
      restrict: 'E',
      scope:{
        ngTitle: '@'
      },
      link: function postLink(scope) {
        scope.title = scope.ngTitle;
      }
    };
  });

Also keep in mind that you shouldn't use "ng" for your custom directives. ng is used for angular natives components. You can (should) keep this naming convention with your application name. Like for an application "MyStats" your could name your components ms-directivename

If you need more informations about the directives bindings you can refer to this documentation

Upvotes: 1

Related Questions