ng-repeat with tables in Angular JS and directives - angularjs

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.

Related

Angular directive. NgTable data loading

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).

Using JustGage with Angular Materal

I want to use JustGage with Angular Material with ng-repeat directive. With one gadge every thing is ok. But when I use it with ng-repeat it doesn't work. I have tried custom directive and plugins also. Is there any way to use JustGage with ng-repeat ? Or any other gadge that works right with angular material.

AngularJs Directives - directive not loading correctly when passing in local scope when creating a dropdown to filter on a list

It is easiest to show what I am doing:
http://plnkr.co/edit/r8Evq3fxg6SWHVoGOvIu?p=preview
I want the filter with the directive to work identically to the filter without the directive. I know that I could lose the
scope: {
filterOptions: "=filterOptions"
},
section and this would work, but I want to make this re-usable, which means using this section. I imagine that I need to also somehow pass customFilter in, using '&', so that it is on the global scope.
Can anyone see the errors that I am making with the scope in this directive?
Thanks in advance,
Yes, you have two problems:
You are doing filterOptions="filterOptions" instead of filter-options="filterOptions"
You are not providing filterItem.
Overall, this is how your HTML should look like:
<my-filter filter-item="filterItem" filter-options="filterOptions"></my-filter>
See Plunker

Creating an AngularJS Directive for jQuery UI Button

Update: Fiddle w/ full solution: http://jsfiddle.net/langdonx/VXBHG/
In efforts to compare and contrast KnockoutJS and AngularJS, I ran through the KnockoutJS interactive tutorial, and after each section, I'd rewrite it in AngularJS using what little I already knew + the AngularJS reference.
When I got to step 3 of the Creating custom bindings tutorial, I figured it would be a good time to get spun up on Angular Directives and write a custom tag. Then I failed miserably.
I'm up against two issues that I haven't been able to figure out. I created a new Fiddle to try and wrap my head around what was going on...
1 (fiddle): I figured out my scoping issue, but, is it possible to just passthrough ng-click? The only way I could get it to work is to rename it to jqb-click which is a little annoying.
2 (fiddle): As soon as I applied .button() to my element, things went weird. My guess is because both Angular and jQuery UI are manipulating the HTML. I wouldn't expect this, but Angular seems to be providing its own span for my button (see line 21 of the JavaScript), and of course so is jQuery UI, which I would expect. I hacked up the HTML to get it looking right, but even before that, none of the functionality works. I still have the scope issue, and there's no template binding. What am I missing?
I understand that there's an AngularUI project I should be taking a look at and I can probably pull off what I'm trying to do with just CSS, but at this point it's more about learning how to use Directives rather than thinking this is a good idea.
You can create an isolated scope in a directive by setting the scope parameter, or let it use the parent scope by not setting it.
Since you want the ng-click from parent scope it is likely easiest for this instance to use the parent scope within directive:
One trick is to use $timeout within a directive before maniplulatig the DOM within a templated directive to give the DOM time to repaint before the manipulation, otherwise it seems that the elements don't exist in time.
I used an attribute to pass the text in, rather than worrying about transclusion compiling. In this manner the expression will already have been compiled when the template is added and the link callback provides easy access to the attributes.
<jqbutton ng-click="test(3)" text="{{title}} 3"></jqbutton>
angular.module('Components', [])
.directive('jqbutton', function ($timeout) {
return {
restrict: 'E', // says that this directive is only for html elements
replace: true,
template: '<button></button>',
link: function (scope, element, attrs) {
// turn the button into a jQuery button
$timeout(function () {
/* set text from attribute of custom tag*/
element.text(attrs.text).button();
}, 10);/* very slight delay, even using "0" works*/
}
};
});
Demo: http://jsfiddle.net/gWjXc/8/
Directives are very powerful, but also have a bit of a learning curve. Also in comparison of angular to knockout, angular is more of a meta framework that in the long run has far more flexibilty than knockout
Very helpful reading for understanding scope in directives:
https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-Prototypal-Inheritance

AngularJS - ng-bind-html-unsafe and ng-model Problems

I have the following line in my html:
<div ng-bind-html-unsafe="departmentConfig" class="control-group"></div>
and I use a $resource get to retrieve the HTML, assign the HTML to $scope.departmentConfig, and then the view is updated perfectly. The HTML that is assigned to $scope.departmentConfig contains form elements, with ng-model attributes in it, but when I change the values in these input elements, they don't update the $scope model at all.
This is what I have tried, based on a lot of other internet posts, and it isn't working:
$resource('resources/sources/departments/:mappedName', {
mappedName:departmentKey
}).get(function(departmentConfig) {
// This will call another function that will build a chunk of HTML
$scope.departmentConfig = $scope.buildDepartmentConfigHtml(departmentConfig);
// This is my feeble attempt to access the element, and bootstrap it to include the items in the $scope model.
var $departmentConfigContainer = $('#departmentConfig');
angular.bootstrap($departmentConfigContainer, ['sourcemanager']);
I have even seen some jsFiddle examples where this appears to be working, but mine isn't. Am I calling bootstrap too soon? I also tried putting a $watch on $scope.departmentConfig like this:
$scope.$watch('departmentConfig', function() {
var $departmentConfigContainer = $('#departmentConfig');
angular.bootstrap($departmentConfigContainer);
});
but it didn't work either. I bet there is an easy explanation to this, I just can't seem to get the input elements with ng-model that are loaded after page compile to get bound to the model. Any help is appreciated, this is the last piece of functionality I need to get working on my page. Let me know if you need more information about my configuration as well.
So, simply put, how can I force a section of the DOM to recompile after I know it has been loaded?
UPDATE
Here is a jsfiddle outlining what I would like to do: http://jsfiddle.net/j_snyder/ctyfg/. You will notice that property two and three don't update the model, and I am calling bootstrap on the outer div, hoping that will include those in the model binding. This is the first time I have posted to jsfiddle, please let me know if you can't see the example.
ng-bind-html is made for regular HTML, not compiling new angular elements.
You will have use the $compile service.
Here is how you would edit your current example to work: http://jsfiddle.net/andytjoslin/ctyfg/21/. But this way ends up being bad, because you have to do DOM manipulation in your controller.
You just need to create a directive that will basically do what you wanted ng-bind-html to do: http://jsfiddle.net/andytjoslin/ctyfg/22/

Resources