I have a model for my view.
That model is array of objects:
var arr = { "12345qwery": { prop1: "value", prop2: "value" } } // contains 500 items
And today I am filtering it in the following way:
arr = $filter('filter')(arr, filterTerm); // contains 4 items
And after this line I get nice filtered data but if I run this filter again I don't have 500 items in it but 4.
So to avoid this I store original array in temporary object and when user change filter I first update arr with backup data (it's original 500 items) and do the filtering.
Now I get in trouble as I have multiple filters and I must restore original data before each filter... anyway it is a mess :)
Is there any better (angular) way to make this in javascript filtering?
UPDATE
To explan better what is issue I created plunker:
https://plnkr.co/edit/99b02UtUfPeM3wl4IiX6?p=preview
As you can see I load markers with objects and want to filter it via text field.
But I can't as I always get some errors.
Am I doing anything wrong here?
And to avoid this and implement filter somehow that is why I decided to do it in code and keep original array after each filter, but this is very complex solution and I wan't to make it in a more natural angular way.
BOUNTY UPDATE
I am filtering object in js
code because I can't find a way to filter markers on this directive in a standard angular way.
That is why I filter in code and before filter always make a copy of it.
I need help to filter marker objects on this directive in a standard angular way.
Plunker implement this directive but I don't know how to filter it.
You're overwriting your array with the new filtered array.
Is the same as
One way to accomplish this is to create two copies of data. keep original same as ever and assign filtered copy of data to map as marker. when ever user changes filter term, apply filter on Original data and assign result to filtered data variable. for instance,
forgive my coding, its just sudo.
Ok.. So you have a few things going on.
Issues
Scoping: Move your scope a bit out. Since you need to use
filterTerm
it needs to be within your controller scope, so move the scope a level out. I moved it out to the<body>
tag - see plnkr.Structure: Try to always include your JS files at the end of the
<body>
tag, and make sure you have the right order. I.e includeangular.js
beforeangular-simple-logger.js
Use of $scope: You can use scope directly, you don't need to extend it, that just makes it harder to read.
Model structure: Your
Markers
elements are a level too deep, I make theMarkers
variable an array of marker objects.Solution
Use Angular's filter, it's pretty good, but need to be used properly. Generally it's like this:
{{ array_to_filter | filter : filter_term}}
So in this case you can use it like so:
<leaflet defaults="defaults" markers="markers | filter: filterTerm " height="480px" width="640px"></leaflet>
Should be working now, just try to search for
London
orPark
.If you use a filter in your JS code it's easier to just make it a function where the variable dies at the end of it's scope. Otherwise you will always be overwriting your variable.
TL;RD
Here's a plnkr containing the working version.
the short answer is
Angular is not destroying array when you do filtering in both cases:
either in HTML
or in JS:
it will be new array.
You need to copy the markers array using angular.copy
Write your customer filter to filter object instead of array
Check out the plunker, write m1, m2, m3 in text-box and tab out. https://plnkr.co/edit/GI4gn5
When you apply an angular filter in your controller, it is a one-shot process. It seems that your use-case actually fits better to applying the filter within the view, like this:
This will leave your model unchanged, but show only the filtered items in the view anyway. This fiddle shows the usage with an input field for the filterTerm.