Comments (1)
I am currently struggling with the same issue. I'm going to write up my thought process so far here. I'm sorry in advance for the lack of clarity. I'm not used to writing tutorials, but I hope this might help someone down the line.
First, I've set up my API to return JSON data with this general structure:
{
"count" : "10",
"pages" : {
"current" : 1,
"total" : 2,
"size" : 5,
"prev" : "#",
"next" : "http://.../api/categories/all/id+category_id+title?size=5&page=2"
},
"items" : [
{"id" : 1, "category_id" : 0, "title" : "Hello" },
{"id" : 2, "category_id" : 1, "title" : "World" },
{"id" : 4, "category_id" : 1, "title" : "Foo" },
{"id" : 3, "category_id" : 1, "title" : "Bar" },
{"id" : 7, "category_id" : 1, "title" : "Soap" }
]
}
This data is for a sample query on the categories
database. I'm following PHP ActiveRecord conventions on table associations, so category_id
represents the parent of each category. I chose to designate category_id=0
to categories that reside in the root, figuring that in SQL, auto-incrementing primary keys start with 1
, so 0
is logically more appropriate than NULL
. This also makes our filtering a bit easier down the line, since JavaScript and NULL
tend to not get along all that well. Please note that I am querying the data with an ORDER BY category_id ASC
.
Based on this article by Oskar Hane, I created this filter:
app.filter('nested', function($filter) {
return function( arr, parent, $key_parent, $key_children ) {
var out = [];
for( var i in arr ) {
if(arr[i][$key_parent] == parent) {
var children = $filter('nested')( arr, arr[i].id, $key_parent, $key_children );
if(children.length) {
arr[i][$key_children] = children;
}
out.push(arr[i]);
}
}
return out;
};
});
I think it's not the most efficient filter, but it works for now. A more efficient filter would likely work with a copy of the initial array made with an array.slice()
, using a count-down while(array.length > 0)
loop, assigning categories to children of the out
array using the array.shift()
method. I think this is also where ORDER BY category_id ASC
would become important, wherein optimization is concerned, since it will assure that the parent is always added to out
before its children. I had trouble writing such a filter, so I'm settling for Oskar Hane's very capable version!
I've set up a $resource
factory. Let's say that I retrieve the categories from the server using this code:
$scope.categories = Category.get();
Now, if I want to, I can create my angular-treeview with this filter:
<div
data-angular-treeview="true"
data-tree-id="tree"
data-tree-model="categories.items | nested:0:'category_id':'items'"
data-node-id="id"
data-node-label="title"
data-node-children="items" >
</div>
However, this is very inefficient, since the filter will end up firing on every $digest
. It seems to be a far better idea to nest the categories right away like so:
Category.get({}, function(data) {
$scope.categories = $filter('nested')( data.items, 0, 'category_id', 'items' );
});
...and then we can simply get the tree working with the above code, but using data-tree-model="categories"
instead of the inline filter. This is the route I'm choosing to take in my project.
Alternatively, you can set up a $watch
to manually apply this filter, as per the conclusion in this article by Ben Nadel. Your code might look something like this:
Category.get({},function(data){
$scope.data.categories = data;
});
$scope.$watch('data.categories', function(newVal, oldVal) {
if( newVal.$resolved ) // $watch is fired once on init
$scope.nested = $filter('nested')( $scope.data.categories.items, 0, 'category_id', 'items' );
});
...and then set data-tree-model="nested"
in our directive. Unfortunately, I could not figure out how to avoid using a callback in the Category.get()
call in this scenario.
Lastly, if you are using the ngResource module to handle API calls, you might be able to filter the results using a custom action with the filter called inside transformResponse
. I haven't tried this route yet, so I cannot provide example code.
Again, I'm sorry for this mess of a comment, but I hope it helps someone who is also dealing with this issue. I'll edit it if I find a better solution.
from angular.treeview.
Related Issues (20)
- How to embed html inside nodes? HOT 2
- Right click on node
- Click but no response HOT 1
- How to make a selected node is not selected
- remove node
- Expand tree while clicking on text HOT 4
- can you add checkbox? HOT 1
- How to add link to files? HOT 1
- Can we do Drag Drop in this Treeview?
- How to include search option in angular tree view?
- Buttons unresponsive after a move HOT 1
- Wiredep not injecting bower dependencies
- Can it work with 'this' instead of $scope?
- custom validation issue
- Is supported Lazy-load child nodes?
- How to change the file icon dynamically.
- One parent folder should be open at a time, rest all parents folders need to be closed
- error [[object HTMLUListElement]] HOT 1
- make accessible via npm
- find a node by Node Label or atleast add all nodes in a list HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from angular.treeview.