Reputation: 514
I am using http request to get data from json file which I than use in controller.
app.controller('mainCtrl', ['$scope', 'loaderService', function ($scope, loaderService) {
//gets data from service
loaderService.getLoadedHtml().then(function (result) {
$scope.fields = result.data;
});
}]);
I need to update directive when this $scope.fields
change as
app.directive('dform', function () {
return {
scope: {
action: '@',
method: '@',
html: '='
},
link: function (scope, elm, attrs) {
var config = {
"html": scope.fields
};
scope.$watch('fields', function (val) {
elm.dform(config);
});
//console.log(config);
//elm.dform(config);
}
};
})
and here is how I am using this directive
<div html="fields" dform></div>
But in my case when $scope.fields changes, i get scope
as undefined in my directive $watch function.
Question:
How can I get the updated value for scope.fields in scope.$watch function?
Upvotes: 4
Views: 945
Reputation: 222319
Usually for directives that should be as transparent as possible, no new scope is supposed be used. Having a new scope also prevents other directives from requesting a new scope on the same element.
If only one of the attributes is supposed to be dynamic, it is as simple as
scope: false,
link: function (scope, elm, attrs) {
scope.$watch(function () { return scope[attrs.html] }, function (val) {
if (val === undefined) return;
var config = {
action: attrs.action,
method: attrs.method,
html: val
};
elm.dform(config);
});
}
Alternatively, bindToController
can be used in more modern, future-proof fashion (depending on what happens with html
, $scope.$watch
can be further upgraded to self.$onChanges
hook).
scope: true,
bindToController: {
action: '@',
method: '@',
html: '='
},
controller: function ($scope, $element) {
var self = this;
$scope.$watch(function () { return self.html }, function (val) {
if (val === undefined) return;
var config = {
action: attrs.action,
method: attrs.method,
html: val
};
$element.dform(config);
});
}
Considering that html="fields"
, the code above will watch for fields
scope property.
Upvotes: 1
Reputation: 38490
You need to give the directive access to fields
by adding a binding for it:
scope: {
action: '@',
method: '@',
html: '=',
fields: '='
}
And HTML:
<dform fields="fields" ...
The value might be undefined
the first time, then you don't want to call dform
:
scope.$watch('fields', function(newValue, oldValue) {
if (newValue === oldValue) return;
var config = {
"html": newValue
};
elm.dform(config);
});
With this HTML:
<div html="fields" dform></div>
You just need to watch html
instead, no need for $parent
or adding fields
as a binding:
scope.$watch('html', ...
Upvotes: 2