I have a promise SharedData which return a variable service .template as well. The value is mytemplate with which I build an url that I ant to pass to templateUrl directive but without success.
app.directive('getLayout', function(SharedData) {
var buildUrl= '';
SharedData.then(function(service) {
buildUrl = service.template + '/layouts/home.html';
console.log(buildUrl); // return mytemplate/layouts/home.html which is the URL I want to use as templateUrl
});
return {
restrict: 'A',
link: function(scope, element, attrs) {...},
templateUrl: buildUrl
}
});
Thanks for helping me!
I resolve my issue using $templateRequest
app.directive('getLayout', function($templateRequest, SharedData) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
SharedData.then(function(service) {
myTemplate = $templateRequest(service.template + '/layouts/home.html');
Promise.resolve(myTemplate).then(function(value) {
element.html(value);
}, function(value) {
// not called
});
});
}
};
});
Here is a Plunker
Hope this will help some people :) and thanks to #Matthew Green
The docs seem to say that the templateUrl can be set asynchronously. However, I have not been able to show that applies to promises. So one way you can do this then while still using a promise would be to add the template to your element in the link function instead.
That would look something like this.
app.directive('getLayout', function($templateCache, SharedData) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
SharedData.then(function(templateName) {
element.html($templateCache.get(templateName));
});
}
}
});
Here is a plunkr to show a full working example. It assumes that the template is loaded into $templateCache so if it isn't you can do a $http.get() for the same effect.
Related
I have angular directive that looks like this
app.directive('paymentsTable', ['$watch', function($watch) {
return {
replace: true,
restrict: 'EACM',
templateUrl: '../views/paymentTable.html',
link: function(elem, attr, scope) {
console.log(elem.$parent.payments); // array
scope.$watch(function(elem) { return elem.$parent.payments }, function(value, oldValue) {
});
}
};
}]);
It gives me
angular.js:13920Error: [$injector:unpr]
When I rewrite first line like this
app.directive('paymentsTable', [ function() {
It gives me another error
angular.js:13920TypeError: o.$watch is not a function
I also use uglify. So, my question is: what is going on here?
The $watch function is part of scope that is handed to you in the link method, therefore there is no need to inject it. The reason you get the second error is the order of the link arguments. Try it like this:
app.directive('paymentsTable', function() { // no need for injection
return {
replace: true,
restrict: 'EACM',
templateUrl: '../views/paymentTable.html',
link: function(scope, element, attrs) { // The correct arguments order
console.log(elem.$parent.payments);
scope.$watch(function(elem) { return elem.$parent.payments }, function(value, oldValue) {
});
}
};
});
I have a Problem with my AngularJS Directive named "showFileBrowser". I want to use Javascript in my Template but it will not be execute in my Browser. Here is my Code:
app.directive("showFileBrowser", function() {
return {
restrict: 'E',
template: '<script>$("#searchNote").fileTree({data: scope.filedata,sortable: false,selectable: false});</script>'
}
});
Someone know why I cant execute Javascript in a Directive or know how to do it?
You dont need to use the id, use 'element' directly.
app.directive("showFileBrowser", function() {
return {
restrict: 'E',
link: function($scope, element, attrs) {
$(element).fileTree({data: scope.filedata,sortable: false,selectable: false});
}
}
});
It works fine if I return a function, but i prefer return an Object.
app.directive("showFileBrowser", function() {
return function(scope, element, attr) {
$(element).fileTree({data: scope.filedata,sortable: false,selectable: false});
}
});
I have text-angular embedded in an directive that has the scope variable... scope.htmlContent.content. In the directive I have
template:
'''
// This updates just fine. I use it to debug so I will take this out from time to time
<p ng-bind='htmlContent.content'></p>
// ng-model htmlContent.content stays blank and does not update
<text-angular ng-model='htmlContent.content'>
</text-angular>
''',
link: function(scope, ele, attr, ctrl) {
//some code
$http({
method: 'GET'
url: 'someurl.com'
}).success(function(data,headers,config) {
// This does not update text-angular
scope.htmlContent.content = data;
// If I add this, it will error out
scope.$apply()
})
}
Anyway, ng-model is not updating properly. Only when I explicitly set scope.htmlContent.content in the beginning of the link function out side of some async fxn then it works. How can I update ng-model?
You need to create a factory for your http get call something like this:
//Please change it as per your needs
app.factory('factoryProvider', function(){
return {
yourData:function(callback){
$http.get('url').success(callback);
}
}
});
Then in your directive you need to inject the factory
app.directive('myDiv',['factoryProvider', function(factoryProvider) {
return {
restrict: 'E',
replace: true,
template: '<p>{{name}}</p>',
controller: function($scope) {
},
link: function(scope) {
scope.data=factoryProvider.yourData;
}
};
}]);
Hope it helps!!
Whats the best way to assign a new value through a directive? A two way databinding.
I have a fiddle here where i tried. http://jsfiddle.net/user1572526/grLfD/2/ . But it dosen't work.
My directive:
myApp.directive('highlighter', function () {
return {
restrict: 'A',
replace: true,
scope: {
activeInput: '='
},
link: function (scope, element, attrs) {
element.bind('click', function () {
scope.activeInput = attrs.setInput
})
}
}
});
And my controller:
function MyCtrl($scope) {
$scope.active = {
value : true
};
}
And my view:
<h1 highlighter active-input="active.value" set-input="false">Click me to update Value in scope: {{active}}</h1>
So what i wanna do is update the scope.active with the given attribute setInput.
Any ideas what I'm doing wrong here?
With element.bind you leave the realm of Angular, so you need to tell Angular that something had happened. You do that with the scope.$apply function:
scope.$apply(function(){
scope.activeInput = attrs.setInput;
});
here is an updated jsfiddle.
I successfully made a jQuery plugin into a directive.
app.directive('bxSlider', function($timeout)
{
return {
restrict: 'A',
link: function(scope, element, attrs)
{
$timeout(function(){element.bxSlider(scope.$eval(attrs.bxSlider))},1);
}
}
});
In my controller (through a click function), I'd like to call a method that is public on the plugin, but I am not sure how to do that. I tried setting the directive to a variable and calling it that way from my controller, but I get the error of ...has no method...
What is the correct way to do this?
You could broadcast an event to trigger your plugin method.
app.directive('bxSlider', function($timeout)
{
return {
restrict: 'A',
link: function(scope, element, attrs)
{
var slider;
$timeout(function() {
slider = element.bxSlider(scope.$eval(attrs.bxSlider));
}, 1);
scope.$on('reload-slider', function() {
slider.reloadSlider();
});
}
}
});
Then in the controller function you use $scope.$broadcast('reload-slider').