Reputation: 23502
I've been using ImmutableJS with Angular 2 for some time, because of it's performance benefits in change detection. See here.
However, I'm not quite sure, why Immutable works with Angular 2 by default. How does it know how to iterate over the values and display them, when there's no explicit array? Does it just call toJS()
every time it accesses the values of the collection? Does it implement some kind of method that Angular 2 automatically calls?
And if so, is there a way to define your own collections which also implement this method?
An example:
Component({
selector: 'list',
template: '<ul><li *ngFor="#item of items">{{ item.id }}</li></ul>',
directives: [CORE_DIRECTIVES]
})
export class SiteComponent {
items: Immutable.List<Item>;
}
Upvotes: 9
Views: 1924
Reputation: 15628
I'm not an Angular user, but I think it's quite easy to see what happens underneath: I'd assume that
ngFor="#item of items"
is transformed to some equivalent of for..of
cycle. This construct can be used for iterating over Arrays, but also can be used with any iterable in general. (And yes, immutable.List
correctly implements iterable protocol)
Some fine resources:
iterable protocol on SO:
Checking whether something is iterable
iterable protocol in depth:
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Iteration_protocols
Finally:
If you want to be 100% sure, create a simple structure that is iterable, but it's neither Array
nor Immutable.List
, so Angular cannot know how to iterate it but to use iterable protocol (requires babel
or new version of node
) :
'use strict'
let obj = {}
// obj is iterable with values 1, 2, 3
obj[Symbol.iterator] = function() {
console.log('Yes, I am using the iterable protocol indeed')
return [1, 2, 3][Symbol.iterator]()
}
for (let i of obj) {
console.log(i) // prints 1, 2, 3
}
Now if you use this structure instead of immutable.List
, you can easily see that the iterator is called.
Upvotes: 5