Is it possible to have ng-repeat use an iterator? - javascript

I have a problem where it looks like I'm going to need to use a Two step view.
The problem is basically that it appears I won't be able to use translate in the view in the way that I get the text as I want. I can solve this by using the translate service in my controller and then rendering the text into a view object there.
I'd rather not iterate over the list multiple times. Is there a way I can use an iterator (some way of saying next() in an ng-repeat statement? so that each time ng-repeat gets the next object, I can transform it then?
<md-list-item ng-repeat="artist in nextArtist() track by artist.name">

Related

Creating a clickable div dynamically with Angular 6

I want the display the user an image, with a varying number of divs (depending on the number of faces detected) which should be clickable (a click on a face will show some attributes for that particular face).
So ideally I would like to create some divs (or buttons) around each face and have something like (click)="divClicked()" for each element.
However,(click) isn't a legit attribute, so, for example, trying something like
d3.select('button').attr('(click)','onClickMe()');
gives an error. onclick is a legit attribute, but by using it I think I should break the way Angular wants me to work (as putting the function inside the component's ts file gives the error onClickMe is not defined).
The very best workaround I could come up with is to assign an id to each div and then do something like
document.getElementById('b1').onclick=this.onClickMe;
but that feels like bad coding.
So, what's the clean way to do that?
I think you should create the div elements by adding a loop with ngFor to your template to display your divs. Of course they may be CSS-styled, based on some properties you have determined beforehand (in particular the CSS properties left and top are useful here). Of course you can add a (click)-event to those divs too.
To do this, your component should hold a list of objects to display which you may update when necessary. Furthermore it should offer a method which gets called when the user wants to see details of a particular face.
The template then only cares for turning those objects into a HTML structure and bind the callbacks.
Structurally something similar to the following will occur in your template:
<div
*ngFor="let face of faces; index as i"
(click)="showFaceDetails(i)"
[style.left.px]="face.x"
[style.top.px]="face.y"
></div>

ko.js twice in a page

Is it possible to have two ko.js in a page? they have different class and id. If it's possible what code do I need to use to have them work together at the moment one of the coded are not working it is being over shadowed by the first one
As I see from your previous question you have 2 view models and you want to apply them to different elements in the HTML.
You can call the applyBindings method with a second parameter- the HTMl element on which you want to apply your view model.
ko.applyBindings(viewModel1, $('.firstdiv').get(0))
ko.applyBindings(viewModel2, $('.seconddiv').get(0))
If the two views/HTML elements are nested one in other you have to use a skipBinding.

Passing value from html to AngularJS controller

I am using Angular Meteor and I have a controller that subscribes to a publish-composite publish which returns two cursors. What I am trying to do is to ng-repeat on one cursor and get value from the second cursor based on the value of the first one. Like this:
{{getName(a.id)}}
where a is one object of the first cursor, and in the controller I have $scope.getName(id) function that returns name from the second cursor, like this:
name = second.find({ID: id}).fetch()[0].name
it worked but the problem is the getName function gets hit for unnecessary number of times. Is there a better way to get data from the second cursor based on ng-repeat object of the first cursor? Is nested ng-repeat the way to do? How can I do it?
Thanks.
It seems as if you are focused on the performance of the ng-repeat. Glad you feel this way! From what I remember, the ng-repeat has been a focus of optimization across many 3rd party libraries and discussions.
In your case, my first attempt would be to bind the value inside the ng-repeat only once. You can do this using the :: syntax on the expression.
For example, this would call the expression once.
<ul ng-repeat="a in items">
<li>{{::getName(a.id)}}</li>
</ul>
At the end of your question you mentioned a nested repeat but your question only mentions a single use of it. Am I missing something?
Disclaimer: I've never used Angular Meteor (or even standalone Meteor) so there could very well be a better way do solve your problem.
via: https://docs.angularjs.org/guide/expression

Performance issue in ngRepeat

I have a ngRepeat block that iterates over an array of objects that draws row accordingly.
One of the properties of the object is a string that requires some transformation before displayed.
Performancewise, is it right to run the function everytime Angular runs its loop?
<div ng-repeat="a in arr">{{ strTransform(a.name) }}</div>
Yes, it is OK, performance-wise and everything, unless:
your transformation function itself is way too expensive, in which case you're doomed, or:
you got a humongous amount of elements to process, in which case you're doomed with the rendering time anyway.
--
As a side note, I'd like to add that you might wanna use an Angular filter (link) for these kinds of operations :)

Is this normal for AngularJs filtering

I'm pretty much new to angular, but I feel like this is kind of crazy.
I've got multiple collections being displayed via ng-repeat in one controller scope. There's an input field for each list to perform a simple query. I was playing around with various filters in my code and I ended up putting a console.log in my filter function. I realized that every time my filter function was called for one list, it was being called for all of the lists in the scope. Furthermore, it was calling the filter function twice each time. So with 3 collections, filtering one of the lists would call the filter function 6 times.
I thought maybe it was just my custom filter, so I tried it out on the default filter function. Same story. Here's my code:
https://dl.dropbox.com/u/905197/angular-filter-test.html
Go to the console and see for yourself :/
What am I doing wrong here? This seems like such a simple thing but it's doing so much work.
This is normal, angularjs uses a 'dirty-check' approach, so it needs to call all the filters to see if any changes exist. After this it detects that you have a change on one variable (the one that you typed) and then it re-executes all filters again to detect if it has other changes.
See the first answer of this question

Categories