Angular JS - data binding in directive does not work

I have a problem with data binding inside a directive that calls another directive.

Here is the basic directive:

var app = angular.module('app'); app.directive("myMainDirective", function ($http) { return { scope: { paramId: '=' }, link: function (scope) { $http.get('some/url/' + scope.paramId+ '.json' ).success(function (data) { scope.idFromServer = data; }); }, template: '<span other-directive id="idFromServer"></span>' } }); 

Here is another directive:

 var app = angular.module('app'); app.directive("otherDirective", ['$http', function(http) { return { template: "<span>{{name}}</span>", scope: { id: "=" }, link: function(scope) { http.get('another/url/' + scope.id + '.json').then(function(result) { scope.name = result.data.name; }, function(err) { scope.name = "unknown"; }); } } }]) 

And the html code that is called by the main directive:

 <span my-main-directive param-id="myObject.id"></span> 

When calling "other-directive", "idFromServer" is not binding and "undefined", so it leads to diplay "undefined".

I probably miss something stupid, but I don’t see that ... (My piece of code is probably not the best, I am pretty new to angularjs, and especially directives, and I tried many ways to achieve what I want .)

+5
source share
3 answers

In my comments, here is one way that can work using the scope. $ watch:

 scope.$watch('id', function(id) { $http.get('some/url/' + id + '.json') .success(function (data) { scope.idFromServer = data; }); }; 

This will be included in the link function in the nested directive.

+4
source

One way, I suggest, not to use two- idFromServer binding ( = ) in the idFromServer variable, use the {{idFromServer}} Interpolation directive to assign a value to the attribute, and then use $attr.$observe , this will be a call when evaluating interpolation.

myMainDirective

 app.directive("myMainDirective", function ($http) { return { scope: { paramId: '=' }, link: function (scope) { $http.get('some/url/' + scope.paramId+ '.json' ).success(function (data) { scope.idFromServer = data; }); }, template: '<span other-directive id="{{idFromServer}}"></span>' } }); 

otherDirective

 app.directive("otherDirective", ['$http', function(http) { return { template: "<span>{{name}}</span>", scope: true, //isolated scope link: function(scope, element, attr) { attr.$observe(attr.id, function(newVal) { http.get('another/url/' + newVal + '.json').then(function(result) { scope.name = result.data.name; }, function(err) { scope.name = "unknown"; }); }); } } }]) 
+2
source

Since javascript is asynchronous, your two ajax requests work mostly at the same time, and id is undefined when the request is made in other-directive .

If you want to try this, just set the default value for idFromServer . The request in other-directive will be executed with the default value.

EDIT: In response to your comment, this is a fairly broad question, and there are many solutions. The best answer I can give you is to simply never run any logic in your link function, just define the behavior and properties of the directive - what is the link function for. The template is used immediately, and you cannot change it.

In this case, you can get the data prepared in the parent area and pass the data in the attributes.

+1
source

All Articles