can element using ng-repeat access variable created by ng-repeat? - javascript

is this valid for ng-repeat in angularjs 1.7.x
<div
ng-repeat="item in items"
ng-class="item.id">
{{tab.label}}
</div>
I am confused with the usage of variable created by ng-repeat ie item in the element which it is attached to. I thought we can use it inside that element only.
I have checked that this works but wanted to understand if there is any example in documentation for this case.
As an extension to this , does ng-controller works the same way for keys attached to $scope.
Kindly give some reference as i have checked for ng-repeat that it works, i just want to understand why( or that it is the expected behavior)

Related

AngularJS Directive - Multiple directives same name

Let's say I have multiple directives with the same name "parent-elem" (on each page I can have a different number of these directives - dynamic number)
<div ng-app="app">
<div parent-elem></div>
<div parent-elem></div>
<div parent-elem></div>
</div>
Is there a way to know (inside the link function) AngularJS finished render all the directives with the same name on the page?
Inside the directive link function - how do I know this directive is the last rendered?
Note: Not using a ng-repeat
You should have had written, same directive, multiple times :P
Now, that totally depends on your directive, how you make it.
It can keep the counter in a service or rootScope may be whenever it is initialized.
If you are using ng-repeat which you should in this case, you have a bool $last that can tell you if the element rendered is last or not, which you can pass to the directive via any attribute.

angular js input bind value

I have an input like this :
<input ng-model="mysearch.myfield" id="myid"/>
that is bound to a filter
<table><tr ng-repeat="row in list|filter:mysearch">...</tr></table>
If I modify the input value in the GUI, it works perfectly, but if I try to modify its value via javascript/jquery
$("#myid").val("newvalue")
The input value is updated but the mysearch.myfield is not modified
Actually, I have a list that appears on user actions (it does not exist on page load):
<li onclick="changeTheInputValue('newvalue1')">newvalue1</li>
<li onclick="changeTheInputValue('newvalue2')">newvalue2</li>
...
with
function changeTheInputValue(v) {
$("#myid").val(v);
}
And it does not work when I click on an "li" (the input value is updated, ut the mysearch.myfield is not modified)
I also tried
<li ng-click="mysearch.myfield = 'newvalue1'">newvalue1</li>
<li ng-click="mysearch.myfield = 'newvalue2'">newvalue2</li>
...
but it does not work :(
Any idea ?
Thanks,
any javascript executing outside the angulars event loop won't be efective in angular untill you apply it. in order to do that you need to get the relevant scope and $apply the changes, since is not clear, how and why you are modifying the value outside the angular scope there is nothing much i can say except you could do something like
function changeTheInputValue(v) {
$("#myid").val(v);
angular.element($("#myid")).scope().$apply();
}
that should let angular know about the changes, how ever this is a bad design if using angular. there are far better ways to accomplish this same thing w/o having mixed execution scopes. (angular/the rest);
You are modifying the value of the input "#myid" using direct DOM manipulation. AngularJS is not aware of this. If you want both the html and the value of mysearch.myfield to update correctly, you must do so by modifying the mysearch.myfield property directly, either in a controller or via an ng-model binding or something similar.
The main reason this isn't working for you has to do with how AngularJS modifies the DOM. When you use jQuery to modify the DOM, you are circumventing angular. Angular has no way of knowing if you have changed something in the DOM except if you do it directly through Angular itself. In particular, if you are curious, read about the $compile and $digest services.
Hope this helps shed some light on the subject!

How to manipulate many elements inside an ng-repeat?

I have an array that I want to show through a ng-repeat. But I have inside the div (with the ng-repeat) many other elements which I want to manipulate for each iteration of that ng-repeat. For example:
<div ng-repeat="data in result">
{{data.name}}
<img src="value">
<p class="class">text</p>
</div>
If I want to change the image source with a different source for each element of my array, how can I do this? I can't change anything of result array. I want to change it later, when the user clic in a bottom for example.
Daniel
EDIT:
img tag was just an example. I added other element which could be necessary to change the class. So a different class for each iteration.
To change the image source, use ng-src like:
<div ng-repeat="data in result">
{{data.name}} <img ng-src="{{data.imageUrl}}">
</div>
In this I am assuming you have a property on each data item called imageUrl.
To change the value, just assign a new value to the imageUrl property and angular's two way bindings will do the rest. An example is:
<button ng-click="result[0].imageUrl = 'img/new-image.jpg';">Change Image</button>
Of course, you would want to make sure you have the correct index and that there is at least one element in the result array, but that should do it!
Live Example
To see this in action, check out the following plunker: http://plnkr.co/edit/gYLH7Z4b03lS2gZBHceC?p=preview
EDIT
Based on the edit to the question - if you need to change the class use ng-class. In fact, there is a directive already written for most of the common things that you need to change. Always search the angular documentation first: angularjs.org. If you do need to do something more advanced that isn't already written, read the documentation and create your own directive: https://docs.angularjs.org/guide/directive. Best of luck!
Use ng-src instead of src for string interpolation. See https://docs.angularjs.org/api/ng/directive/ngSrc.

How to 'destroy' a directive in AngularJS?

I'm using a directive to separate the logic for an entity (for example, a person).
So I have a people service that stores an array of people like:
this.people = ["Person 1", "Person 2", "etc"];
The controller then injects that service, and sends data to a template that contains my directive. So my template looks something like:
<div ng-repeat="person in people">
<person name="person"></person>
</div>
Now, in my directive I have a delete function (called by clicking a button in the directive's template, which looks something like this (People service also injected into directive):
delete People.people[id];
The problem is, the rest of my directive's template remains intact. I want to remove the directive completely upon deletion. How is this possible? I've tried hiding it by using ng-hide and setting a 'deleted' property in the directive's scope to true upon deletion, but the empty (without data) directive template remains. I've looked into scope.$destroy(), element.remove(), etc, but nothing has worked and nothing seems really clear in the documentation...
How can I destroy/remove a directive completely from within itself (i.e. upon calling a delete function)?
Fiddle: http://jsfiddle.net/VSph2/107/
Click delete and the data is gone, but the directive (and template) remains, showing 'name:'. How can I remove the directive completely on delete?
You are deleting object, but empty element in array remains, it is just null reference instead of pointing to an existing object.
Use
this.peopleIds.splice(this.peopleIds.indexOf(personId), 1);
to remove it from array, and that element will not be rendered in for loop anymore.
Reference: How do I remove a particular element from an array in JavaScript?

Angularjs - ng-model undefined

I am building a rather complex directive in which I need access to ng-model on a specific element in the template which is enclosed into ng-if directive... I have a plunker and the explanation on how to see the issue is below.
In the .compile function of the directive I have a line of code that looks like this
ngModel = elm.find('textarea').controller('ngModel');
console.log(ngModel);
In my template, I have a something like this:
<div ng-if="views.view">
<textarea ng-model="exp.val"></textarea>
</div>
When I use ng-show my console.log gets an object of ng-model, no problem ...
The requirement is very strict however and I have to use ng-if. When I use ng-if my console log gets undefined
The actual working version of the problem exists in this plunker
If you change the line 6 in template.html into ng-if you can see the behavior.
How do I have to write this line to retrieve the model when inclosed in ng-if.
ngModel = elm.find('textarea').controller('ngModel');
I also tried using attach-if directive by Simon Sparks. This directive is pretty cool, it preserves the scope unlike ng-if so if you specifically need to not render HTML but you need to preserve scope it works great.
I still have the same problem with invoking ngModel as I am doing it but because of applying custom filters in the directive I have to update ng-model in this way.
I am this one step away from finishing this directive. Hoping someone can help.

Categories