Dimitris Papazacharias
Dimitris Papazacharias

Reputation: 691

Angular directive scope does/not pass to linking function

I'm having a problem which seems completely crazy! I use a directive that takes some attributes bound to its scope, that take a value from a parent scope variable. All very normal.. ...except when I do console.log(scope), the attributes are displayed normally as scope object's properties with the expected value, but when I do console.log(scope.myAttr) then I get undefined!!

Has anyone encountered something like this before??

   // In parent directive:


scope.datepickerOptions.enableTime = false;




// In directive:

angular.module('myModule')
	.directive('datepicker', function() {
		return {
			require: 'ngModel',
			restrict : 'A',
			scope: {
				format: '@',
				enableTime: '=',
				minDate: '@',
				maxDate: '@',
				mode: '@'
			},
			link : function(scope, element, attrs, ngModel) {
				console.log("scope")
				console.log(scope)
				// displays all properties with expected values
                //=> scope.enableTime: false

				console.log("enableTime")
				console.log(scope.enableTime)
        // undefined (!!!)
        
        
        ...
   // In parent template:

...

<input
  type="text"
  id="events_date"
  name="events_date"
  ng-model="events.selectedDate"
  placeholder="Select Date Range"
  ng-change="setQueryDate()"
  format="d M Y"
  mode="range"
  enable-time="datepickerOptions.enableTime"
  max-date="today"
  datepicker>
  
  
  ...

I also tried: enable-time="{{datepickerOptions.enableTime}}" with enableTime: '@'

and I get the same craziness when I do console.log(attrs) and console.log(attrs.enableTime)

Same thing when I put a controller with $scope argument: console.log($scope) displays everything normally, but console.log($scope.enableTime) gives undefined

Upvotes: 1

Views: 445

Answers (3)

Dimitris Papazacharias
Dimitris Papazacharias

Reputation: 691

It seems that if I do

$timeout(function(){
  console.log(scope.enableTime)
}, 600)

//and in parent directive

$timeout(function(){
  scope.datepickerOptions.enableTime = true //or whatever
}, 500)

everything falls into place. But it doesn't seem to me like a clean solution. After all, I've never encountered something like this before, and how can anyone be sure when his/her directive will load and render??

Upvotes: 0

Hoyen
Hoyen

Reputation: 2519

I think what is happening is that you are setting enableTime after the directive is created. If that is the case you can use the 'ng-if' directive to check if it is defined first before loading it.

Here's an example of what I think is happening:

var app = angular.module('test', []);

app.controller('MainCtrl', function($scope, $timeout) {
  $scope.datepickerOptions = {}
  $timeout(function() {    
    $scope.datepickerOptions.enableTime = false;
  }, 500);
});
app.directive('datepicker', function() {
  return {
    restrict: 'A',
    scope: {
      enableTime: '='
    },
    link: function(scope, element, attrs, ngModel) {
      console.log("scope")
      console.log(scope)
        // displays all properties with expected values
        //=> scope.enableTime: false

      console.log("enableTime")
      console.log(scope.enableTime)
    }
  }
});
<!DOCTYPE html>
<html ng-app="test">

<head>
  <script data-require="[email protected]" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
  <input datepicker ng-if="datepickerOptions.enableTime != null" enable-time="datepickerOptions.enableTime" />
</body>
</html>

Upvotes: 1

P.S.
P.S.

Reputation: 16384

I don't see any scope variables in your directive. If you want to keep any attribute value as scope variable, just do something like this:

scope.yourVariable = attrs.yourAttribute;

Upvotes: 0

Related Questions