AngularJS : Directive not able to access isolate scope objects
Solution 1
The problem is: at that time angular does not update its bindings yet.
You should not access your variables like this, try to use angular js binding mechanism to bind it to view (by using $watch for example). Binding to parent scope variables means you're passive, just listen for changes and update other variables or your view. That's how we should work with angular.
If you still need to access it. You could try a workaround using $timeout
$scope.setDefaults = function() {
$timeout(function () {
alert(JSON.stringify($scope.appSubs)); //Coming as undefined
},0);
};
It's better to use $watch
angular.module('ctrl', []).controller('TempCtrl', function ($scope, $location, $rootScope) {
$scope.appSubscriptions = "Subscriptions";
$scope.appObj = "Objs";
$scope.showAppEditWindow = function () {
//Binding the directive isolate scope objects with parent scope objects
$scope.asAppObj = $scope.appObj;
$scope.asAppSubs = $scope.appSubscriptions;
};
});
angular.module('ctrl').directive('tempDirective', function () {
return {
restrict: 'E',
replace: true,
scope: {
appObj: '=asAppObj',
appSubs: '=asAppSubs'
},
link: function (scope, element, attrs) {
},
controller: function ($scope, $timeout) {
$scope.$watch("appSubs",function(newValue,OldValue,scope){
if (newValue){
alert(JSON.stringify(newValue));
}
});
},
template: "<div>{{appSubs}}</div>"
};
});
By using $watch, you don't need to broadcast your event in this case.
Solution 2
Most likely the isolated scope variable is not available when the directive's controller first instantiates but probably its available when you need it for a following event such as: within a function bound to an ng-click
its just a race condition and the object doesn't arrive exactly when directive's controller loads
Akhilesh Aggarwal
Updated on June 14, 2022Comments
-
Akhilesh Aggarwal almost 2 years
I am trying to put some default values in my directive with Isolate scope. Basically, I need to do some DOM manipulations using the scope object when my directive is bound. Below is my code:
Controller:
angular.module('ctrl').controller('TempCtrl', function($scope, $location, $window, $timeout, RestService, CommonSerivce) { $scope.showAppEditWindow = function() { //Binding the directive isolate scope objects with parent scope objects $scope.asAppObj = $scope.appObj; $scope.asAppSubs = $scope.appSubscriptions; //Making Initial Settings CommonSerivce.broadcastFunction('doDirectiveBroadcast', ""); };
Service:
angular.module('Services').factory('CommonSerivce', function ($rootScope) { return { broadcastFunction: function(listener, args) { $rootScope.$broadcast(listener, args); } };
Directive:
angular.module('directives').directive('tempDirective', function() { return { restrict : 'E', scope:{ appObj:'=asAppObj', appSubs: '=asAppSubs' }, link : function(scope, element, attrs) {}, controller : function ($scope,Services,CommonSerivce) { //Broadcast Listener $scope.$on('doDirectiveBroadcast', function (event, args) { $scope.setDefaults(); }); $scope.setDefaults = function() { //Setting Default Value alert(JSON.stringify($scope.appSubs)); //Coming as undefined }; }, templateUrl:"../template.html" }; });
Custom Directive element:
<temp-directive as-app-obj="asAppObj" as-app-subs="asAppSubs" />
Now, the issue is that while trying to access the isolate scope in the default method inside directive, I aam getting an undefined value whereas the data is coming and is getting bound to the DOM. How can I access the isolate scope in the broadcast listener and modify the directive template HTML? Is there another wasy for handling this?
-
Khanh TO over 10 years@Akhilesh Aggarwal: You should use $watch for this. Check out a similar problem at stackoverflow.com/questions/19142409/…
-
Akhilesh Aggarwal over 10 years@Khank To: This is even better :). Any particular reason why the 'watch' definition should be added inside 'link'. I tested and it works under 'controller' also.
-
Khanh TO over 10 years@Akhilesh Aggarwal: In your case, I think you should use $watch inside
controller
. As controller should contain your logic and link function should only care about making a dynamic connection between model and view -
Seth Flowers almost 10 years@KhanhTO: According to the angular docs for directives: "Best Practice: use controller when you want to expose an API to other directives. Otherwise use link."