3

I have an issue with my AngularJS code.

It seems I can't access my directive scope from my controller.

The directive

app.directive('PaginatedText', function(){
    return {
        restrict: 'E',
        scope: {
            text: '='
        },
        controller: 'PaginatedTextController',
        templateUrl: '/frontend/views/paginated-text.html'
    };
})

The controller

app.controller('PaginatedTextController', ['$scope', function($scope){

    $scope.page = 1;

    $scope.limit = 200;


    console.log($scope, $scope.text);

}]);

The directive call

<paginated-text text="character.long_description"></paginated-text>

The template

<p>
    {{text}}
    <button>read more</button>
</p>

The printed console.log: console.log

Any idea why console.log($scope.text) print undefined ?

Community
  • 1
  • 1
ChainList
  • 1,198
  • 7
  • 28
  • 1
    Use @ symbol for text – PavanAsTechie Jun 23 '15 at 12:28
  • No, using '@' will set $scope.text at "character.long_description". My code code won't be eval that way. – ChainList Jun 23 '15 at 12:30
  • 2
    use bindtocontroller and controllerAs instead of scope – LionC Jun 23 '15 at 12:31
  • 2
    This is very common when the actual value of a primitive var is set after the controller is initialized. The console deceives you: the `$scope` is printed as a reference. When printed, the `text` is undefined, when you expand the `$scope` in the console, it has been defined. So: `character.long_description` is given the value `'

    Lorem ipsum...'` *after* the controller is called. Add a watch for its value and take action there to correct your problem.

    – Nikos Paraskevopoulos Jun 23 '15 at 12:32
  • @NikosParaskevopoulos I understand... Funny console though ! It works great by the way ! Thank you ! Is this clean (I mean not dirty) to do a $watch just for this little change ? – ChainList Jun 23 '15 at 12:35
  • @LionC thanks for the bypass ! :) I love that way too, which one do I have to use ? – ChainList Jun 23 '15 at 12:37
  • Sorry for the third post in a row. The @NikosParaskevopoulos solution suits better in my case. Thanks to both of you ! – ChainList Jun 23 '15 at 12:42
  • 1
    The "i" icon at the end of the first console.log print is precisely for what Nikos has mentioned. http://stackoverflow.com/a/18098661/1235243 – Bharat Jun 23 '15 at 12:47
  • @Bharat I don't even know that "feature" thanks for pointing this out ! – ChainList Jun 23 '15 at 12:50
  • *"Is this clean...to do a $watch just for this little change"*: I feel your worries. If this directive is to be used 10s of times in a view, you may want to consider some other solution. Otherwise I expect the performance hit to be negligible. It may be possible to do the listening in a setter with `Object.defineProperty`. – Nikos Paraskevopoulos Jun 23 '15 at 15:22

1 Answers1

0

Directive names must start with lowercase!

app.directive('paginatedText',

angular.module('app', [])

.run(function($rootScope) {
    $rootScope.character = {
      long_description: 'LirumLarum'
    };
  })
  .directive('paginatedText', function() {
    return {
      restrict: 'E',
      scope: {
        text: '='
      },
      controller: 'PaginatedTextController',
      template: '<p>{{text}}<button>read more</button></p>'
    };
  })
  .controller('PaginatedTextController', ['$scope',
    function($scope) {

      $scope.page = 1;

      $scope.limit = 200;


      console.log($scope, $scope.text);

    }
  ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"></script>


<div ng-app="app">
  <paginated-text text="character.long_description"></paginated-text>
</div>
Michael
  • 3,085
  • 1
  • 17
  • 15