I use Angular to operate on table and I have a button to delete a row. I have also written a directive to it. The problems is when I add some new rows dinamically also using Angular the buttons don't work. I read a little bit about it and found out that I should use $compile, so I did. But something is wrong and doesn't work. Here comes the plunk which, I hope, will clarify my problem:
plunker
could you tell me how to make it work?
you have a mistake in $compile. You simply compile wrong html element here is Plunker
Related
I am developing a mobile application with left and right drawer, using mmenu (http://mmenu.frebsite.nl/) it is working fine till I've decided to populate items of the right menu on the fly. My app is based on angularjs and all directives of angularjs in body are working fine except all directives inside <nav id="menu-right">somehow, angularjs directives inside the menu definitions are not executed. I am not sure if it is something related with the order of executing javascript. Any help will be really appreciated. Thank you !!
UPDATED (07-April)
An example in jsfiddle http://jsfiddle.net/jmhostalet/wcK8L/
"My controller says" is working in the body but not in the mmenu, in body prints "Hello" but in mmenu prints nothing
The problems you were running into were:
First off the was not included in the declaration
You are changing the DOM without angular knowing about it therefor it does not have a chance to compile the braces {{myCtrlVar}}
It seems like extra work to create a directive but in the long run will allow you to reuse your code more. Also if you are like me and have bad javascript habits; it is nicer to use a framework to keep things straight.
My solution the in the plunker below shows "one way" to do what you are asking. It would be interesting to port the entire MMenu code over to an angular module in order to have more parameters and control.
(Never heard of MMenu, but seems like a cool project -- I will look more into it).
Plunker
(sorry I am inept at using fiddler)
Your fiddle doesn't have controller initialization on #menu-right but on his sibling element and therefore {{myCtrlVar}} expression can't access controllers scope objects.
A plunker for this question is at http://plnkr.co/edit/CfIryhwmlpme1ZSfnEom?p=preview
I need help with various issues here:
The first is that the plunker isn't exactly working as I expect...why? It should print the types of the data used in the directive attributes.
In my real app, I can't seem to get the use of the $parse service in directives. I've tried various approaches and can't get the thing to work. Simple attributes work ok in the real app.
I think the directive template is ok as coded but if not please like to hear your comments.
Thanks in advance!
Is this what you are looking for
Plunkr
I have changed your watch expression
scope.$watch('item', function(item) {
inventoryUpdates++;
console.log("inventory status["+inventoryUpdates+"]==>item="+item);
scope.itemName = item.rack1.name;
scope.itemCount = item.rack1.count;
},true)
Should it look Like this?
Plunker
regards
I'm having a really specific, strange issue.
We have to code our app to support IE8. We are wrapping the Angular-Bootstrap's Typeahead directive in a template to encapsulate a lookup widget with some extra functionality.
The issue we're having is that our directive template looks like this:
'<input ng-model="typeaheadValue" typeahead="xxx.code as formatXxx(xxx) for xxx in searchXxxs($viewValue)">'
Inside the link function in the directive we are simply calling replace: true and passing in some values to the scope.
This works beautifully in both IE8 and Chrome.
Now, the REALLY strange part is that, for IE8 only, if we say in the HTML in which we're using the directive:
<input type="text" search-directive>
It will not ever get into the link function. If i take the type="text" off everything works perfectly.
I created a simple JSFiddle to mimic what we're doing with a really basic test. Unfortunately for me the JSFiddle doesn't work in IE8 - but this is basically what we're doing. This can be found here: http://jsfiddle.net/lungsponge121/8xGuF/ (this is my first fiddle, not sure if it's editable or not)
After fighting with it for hours I've found the following: if i keep the html as (input type="text") and i replace the directive template input element with label or textarea it works fine, but when i use input it does not work at all. I also removed all of the typeahead code from the template and found that in IE8 it still doesn't work. The IE8 console did nothing for me and just gave me the standard illegal operation.undefined error.
I had somebody I work with help me debug my code and right now we're wondering if this is a bug. Has anybody else run into this - I'm thinking of submitting this to the Angular people as I can't find out how to get around this.
One thing jumped out at me: your directive is doing replace. The markup of the template you are replacing it with does not have the type="text", whereas the original markup does. I have noticed that replace does a sort of merge, and it may be getting confused when trying to merge or replace some HTML that has an attribute with a template that does not.
Interestingly, you don't really need to replace the original markup with a template at all. That is one use of directives, but not the most powerful in my opinion. Take "replace" off and remove the template entirely, if you're just trying to extend the typeahead anyway. In my own projects, for example, I might put several different directives attributes on a single element and they all add their own flavor of extra functionality to the existing element. All of them have a reference to the same $element, you just have to be careful that they don't conflict.
I wrote the rest of this before I looked at the fiddle first, sorry.
I'm on a chromebook so I can't test the IE8 thing, but if I recall IE is very picky about HTML attributes. Have you tried any of the following:
Alternate directive specification, as in data-search-directive
Make sure the directive has a property, as in search-directive="", even if you don't use it
Is the template cache really necessary? Have you tried this just by putting the template in a template property of the directive?
Is IE8 happy without "use strict"?
Have you seen the angular ui bootstrap alternative typeahead? At the very least, looking at what they did may give you ideas of how to do what you are trying to do.
I have a simple form with two input boxes of number type. When i try to add max attribute via directive, it seems to ignore it and doesn't validates although attribute is added on the dom element. When i add it inline it works.I referred this question AngularJs can't read dynamically set attributes but that did'nt seemed to help me.New in angularJS and completely clueless.
Any help appreciated.
Edit: Updated fiddle
Demo http://jsfiddle.net/tNUNh/6/
Didn't look furthuer, but one solution you have is to recompile the element everytime you change its max value.
Just change inject $compile (module.directive('type', ['$compile', function ($compile) {) and after attr.$set('max', '100') call $compile(element)(scope).
This doesn't seem right, but I'd need to look further into input directive code to see if it exposes a way to change it without recompiling.
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/