In my AngularJS application I use directive to have flexible ability of template using. One of templates contains ngTable. Data for ngTable was loaded correctly from server till it was not wrapped with directive. To fix this issue I tried using onload event for including template to call method of parent controller. Seems i did not fix scope issue for ngTable, because as I can see getData: function(params) was not called. I think it was not called because of new NgTableParams was called\created in controller scope, not in directive.
Is any ideas how it can be fixed?
Great thanks to Mark Rajcok. In directive I changed scope in next way:
scope: true
All explanations and details here. So problems of injecting ng-table using directive is solved (possible it is not best way, but it is completely useful for me).
Related
I have a custom scope method within a Controller, and when a custom directive loads, I want to run a method inside the defined controller. I've seen a lot of options, but which one could be referenced inside a template via an ng-* call? Otherwise, what are the best options?
Since the controller is instantiated when the directive is loaded, any method called in your controller will be called on page load. In my code it is often something like
angular.module('app')
.controller('controllerName', ctrl);
function ctrl() {
/*--------Initialize--------*/
someMethod()
}
If you are on angular 1.5 already and can use the new component way to build your custom directive, you could use the newly introduced $onInit method instead of polluting the constructor, that should only initalize the object itself.
For details, please see this blogpost: https://toddmotto.com/on-init-require-object-syntax-angular-component/
I have a one-page site that I am building out and this is my first time using Angular on a site. Building it on top of Laravel too for the backend but that is beyond the scope of this question.
I need to be able to open a modal on a main page view which will add a new resource (e.g. a new client) or edit a resource. I want to somehow get the form's html inside the modal body when the $uibModal.open()'s controller is called and set the $scope.modalBody equal to the injected items.modalBody (the only way this works is if I use:
$scope.modalBody = $sce.trustAsHtml(items.modalBody);
The only problem now is that anything inside the HTML body, Angular will not use it's magic and do any data-binding. It is still in the raw form of
{{ object.property }} or since I'm using Laravel and avoiding conflict with the Blade template engine:
<% object.property %>
See screenshot:
screenshot
I have been banging my head against the wall on this one...I have tried putting $scope.$apply() in my directive and my controller, neither of which worked. I have a feeling that is the source of my problem though. I have also tried making the html just a <new-client></new-client> directive and using templateUrl: 'views/clients/add.php' which would be ideal, but the template is not being included inside the <new-client></new-client>.
I'm using ui-bootstrap 0.14.3 and Angular 1.4.8.
Could this be a bug? Or am I doing something wrong? Anyone have a better way of getting a form into my modal? Let me know what code you want to see so I don't clutter this post with unnecessary code blocks.
I have come across a similar issue with using jQuery's AJAX to receive template strings and append it to a server.
So when HTML is added via jQuery, bound html string, etc., angular doesn't know it needs to automagically compile this data.
What you need to do is use the $compile service, to $compile your html and then attach the correct $scope to it:
`$compile('jQuerySelectorReturningHtmlOrAnHTMLStringThatNeedsToBeCompiled')($scope);`
There are multiple examples in Angulars Documentation for $compile that can give you an idea of what is happening. I think by what you have described the same thing is happening here in your situation.
The key is to call this $compile service function after the html has been bound to the page.
EDIT:
There are a few other options based on some comments, that will serve as a viable solution to rendering this content on your view. For example a directive that takes a string attribute representing the HTML string of your desired view.
1. Modify your directive template in the compile step:
You have the ability to modify your template before the directive compiles and binds any attributes to it, to that directives scope:
app.directive('myAwesomeCompileStepDirective', [myAwesomeCompileStepDirectivef]);
function myAwesomeCompileStepDirectiveFn() {
return {
restrict: 'EA',
compile: function compileFn(tAttrs, tElement) {
//Here you can access the attrs that are passed into your directive (aka html string)
tElement.html(tAttrs['stringThatYouWantToReplaceElementWith']);
return function linkFn(scope, element, attrs, controller, transcludeFn) {
//if all you want to do is update the template you really don't have to do anything
//here but I leave it defined anyways.
}
}
}
}
You can view a file I wrote for a npm component which uses this method to modify my directive template before it is compiled on the page & you can also view the codepen for the complete component to see it in action.
2. Use $compile service to call $compile in link function using directive attrs.
In the same way as the aforementioned method, you can instead inject the $compile service, and call the function mentioned above. This provides a bit more work, for you but more flexibility to listen to events and perform scope based functions which is not available in the compile function in option 1.
I want to do something like that, Can it be possible in angularjs
ng-change=\"myDirective = [test]\"
i.e. I simply want to call my directive on ng-change , is it possible in angularjs to call custom directive inside directive.
yes it is possible but for doing this you need another directive for watching changes on your myDirective variable...
when you change value of myDirective middleware directive catches changes and rebuild dom.
I created such a directive for another problem but it can be used in your situation so I edit this PLUNKER for you...
I'm using a custom jquery plugin which transforms table to a tree. And when i'm loading data from ng model i need to recall plugin's constructor. but i can not find that event, when i need to call that.
I've tried to $watch model variable - doen't work well
You should create a new directive instead of doing this in a controller.
By using a directive, you'll be sure that the code located in its link function is applyed after DOM complilation.
It is intended to do what you want.
see http://docs.angularjs.org/guide/directive
I am trying to build a responsive data table using Angular with a directive and ng-repeat. I have managed to get the ng-repeat to work with tables: http://jsfiddle.net/raff77/Asb8k/
{}
I am now trying to get it to work with a directive and the ng-repeat does not work. http://jsfiddle.net/raff77/uwGXb/3/
{}
Is there a way to get the ng-repeat to work with your directive or should you build that into your directive. Notice I have built out a solution to add the rows as strings then html but i want to avoid this and do things the Angular way.
You are creating a new scope in the directive as shown here
scope: {
gbsdata: '='
},
But "chartdata" is the array you were watching, which is not available in this scope.
scope.$watch("chartdata", function (chartdata) {
Check this fiddle it will help you. http://jsfiddle.net/KLGrV/1/
There seems to be a bug in AngularJS when you want to put 'td's into a table in a directive. See this question Angular Directive Does Not Evaluate Inside ng-repeat and particularly this answer: https://stackoverflow.com/a/15755234/669561.
https://github.com/angular/angular.js/issues/1459
And I don't really see, why you want to fill up the table with a directive. Your first approach without the table seems to work perfectly fine and I cannot see any advanteges over using directives.