We were unable to load Disqus. If you are a moderator please see our troubleshooting guide.

Nate • 9 years ago

> bingings.shouldBePropagated();

Not so sure about propagating bingings!!!

Sebastian Sebald • 9 years ago

So Angular 2 basically uses the Flux Architecture? :-)

Victor Savkin • 9 years ago

Angular will not force an architecture on you, but the new change detection and the Forms API, which I will write about in detail soon, make Flux a good option.

Btw, you can already build Angular 1.x apps using Flux http://victorsavkin.com/pos....

Ole-André Johansen • 9 years ago

Angular 2 doesn't come with any architecture strings attached? Can you clearify?

Foo • 9 years ago

Interesting stuff, thanks! One question: how exactly do observables avoid cascading updates? My understanding is that in Angular 1.x, cascading updates are dealt with by repeating the $digest() loop until no further changes are detected. Won't that still be true? Thanks to the new immutable and observable features you outline, each loop will have less to process, but it still needs to repeat until a stable state is reached, right?

Victor Savkin • 9 years ago

Thanks.

In Angular2 we walk the change detection graph only once (TTL = 1). This is possible because the graph does not have any cycles.

What I meant by cascading updates is the following:

Say we have three observable objects: ObjectA, ObjectB, ObjectC. Consider the following situation.
- ObjectA fires an event
- The view rendering ObjectA catches the event and rerenders
- ObjectB catches the event and fires its own event
- The view rendering ObjectB catches the event and rerenders
- ObjectC catches the event and fires its own event
- ObjectA catches the event fired by ObjectC
...

Note how the framework calls (view.render) are interleaved with the events. It is hard to tell what gets rerendered when. This is a real problem of many front-end frameworks.

In Angular2 it works as follows.
- ObjectA fires an event
- ObjectB catches the event and fires its own event
- ObjectC catches the event and fires its own event
- ObjectA catches the event fired by ObjectC

While it is happening the framework is marking the parts of the change detection graph that are updated. This marking has no observable side effects. At the end of the VM turn the framework will check only the marked paths and update the bindings.

Note that there is a clear separation of when the model is updated and when the framework does its magic. The bindings would be updated in the same order if ObjectA, ObjectB, and ObjectC were not observable. This is very important.

Gabriel C. Troia • 8 years ago

Hi Viktor, I'm pretty late to the party, but this is really cool stuff.

From what I understand, Angular1 runs the digest every time a change occurres (an event is fired), which has performance side effects, while Angular2 runs in 2 different phases:
- 1st phase: listening to the events and marking the changed components
- 2nd phase: rendering the new state (which contains only the marked components, thus being way faster).

My question is, when is phase 2 kicking in, or how does Angular know when to start it?

Victor Savkin • 8 years ago

The first phase is reacting to events and updating components and domain objects. Btw, nothing gets marked unless you use ON_PUSH components.

The second phase is rendering the new state. Angular knows when to run it because it is built on top of Zone.js. Zone.js provides hooks that are invoked on every browser event and every mircotask. Angular uses these hooks to rerender the view.

Gabriel C. Troia • 8 years ago

Great. Thanks a lot for the answer.

Sekib Omazic • 9 years ago

So to use immutable objects I have to inform angular2 about it by implementing onChange method in the component? And if I want to use observables I'd have to use objects of type Observable?
A working TodoApp would help better understand the change detection in A2.

Victor Savkin • 9 years ago

>> So to use immutable objects I have to inform angular2 about it by implementing onChange method in the component?

You can use immutable and observable objects without telling Angular about it, but then you won't get any performance benefits out of it. To get the performance benefits you need to tell the framework that you depend only on immutable or observable objects.

>> And if I want to use observables I'd have to use objects of type Observable?

You won't have to use any special Observable class. Any push-based object can be used here (e.g., Object.observe or Rx observables). The framework does not make any assumptions about the type of your observables. Likewise, the framework does not make any assumptions about what is immutable.

>> A working TodoApp would help better understand the change detection in A2.

I am putting something together that will show advanced scenarios of using the change detection.

Badru • 9 years ago

Waiting for that "something together" victor. It will help to understand better.
One more question, the above syntax is not native js. Is it AtScript syntax?

TheJeebus • 9 years ago

>> To get the performance benefits you need to tell the framework that you depend only on immutable or observable objects

And how exactly does one do that? Your post is very unclear on this particular point.

Victor Savkin • 9 years ago

You do that by setting the change detection strategy to ON_PUSH, which means that only when bindings are pushed, the component's view should be checked.

@Component({
changeDetection:ON_PUSH
})
class DependsOnlyOnImmutableData {}

José Pedro Silva • 8 years ago

Hi Victor,

How can we inform angular that there are changes on the component (when using ON_PUSH)?

Can we be running outside angular's zone and still do this?

Victor Savkin • 8 years ago

You can. Call `markForCheck` on a change detector ref, and then call LifeCycle.tick.

TheJeebus • 9 years ago

Perfect, thanks!

vivainio • 8 years ago

How does angular 2 know to wait for change of "todos" or "todo" variable? Do all of the expressions within the template create a watch that triggers re-rendering of the component if

1) reference changes (in case of ON_PUSH change detection) or
2) variable is an Observable and the observable fires

?

Victor Savkin • 8 years ago

When not using OnPush detectors, then it just checks all bindings on every browser event similar to Angular 1.

When using OnPush detectors, then the framework will check an OnPush component when any of its input properties changes, when it fires an event, or when an observable fires an event.

vivainio • 8 years ago

Your observable example didn't have OnPush, so I'm not sure I understood it quite yet ;).

Debanjan Basu • 8 years ago

Hi Victor, I am a big fan of your works. I am designing an inventory prediction system based on angular2 and following the webcomponent standards. Thereby I have encountered certain problem on the way. 1) Whenever I inject a dependecy it by default gives me a new instance of the component. 2) Change Detection algorithm is still a bit not clear to me. It is always evolving, but certain fundamentals could have been achieved using observables. I have made a small diagrame if you can help me to achieve this particular feat:

The idea is very simple: The user clicks on a slice of the pie -> This calls the api and populates sales data using fetch (still hate angular2 http) -> changes the data in salesforce -> triggers the salesforcegraph to change.

If you are interested I can share the code with you somehow.the github is : https://github.com/debanjan...

Victor Savkin • 8 years ago

Thanks for your enthusiasm for Angular! Unfortunately, we're really busy working on delivering Angular 2 beta right now, and it's not possible for me to respond to individual requests for help. The best way to get help would be to post on the public list (e.g., stackoverflow).This will also help other community members

Manfred Steyer • 8 years ago

In the observable-sample above, what would happen, if the first todo-item-component had some sub-components. Will they be checked too, when the first todo-item-component raised an event?

Victor Savkin • 8 years ago

If you have the following component tree

A
|
B
|
C

And B raises an event, A and B will be checked. If, however, C gets updated during the check, then C will be checked too.

Manfred Steyer • 8 years ago

I see. In this case, C would also have to raise an event, when it it is updated during the check, right?

Tim Kindberg • 8 years ago

Victor Savkin would you have mix the use of Observables with Immutables? Or does using one make the other unneccessary?

Victor Savkin • 8 years ago

I think using the two in the same app is totally reasonable.

Simple immutable objects are great for representing records, static collections, and in general facts. Rx Observables are useful for expressing variable things.

For example, a todo and a list of todos can be immutable. But the notion of the current list of todos is mutable. An observable of immutable lists of todos is a good way to model this.

Tim Kindberg • 8 years ago

Thanks! I would LOVE to see a post about how to properly mix the two with real code examples.

Csaba Tamas • 9 years ago

How can I manual run change detection or subscripe it for example in component.js
this.service.ajaxCall((result) => {
this.todos = result.todos; //change
this.findNewElementInDOM(); // dont't work
--> Don't runned the change detection here, but I only can here cach the async call and detect change
});
--> change detection only run after ajaxCall callback executed

ajaybeniwal • 9 years ago

Its nearly similar to React and Flux using immutable.js along with it

Manfred Steyer • 9 years ago

I'm wondering, when the digest-phase is triggered. You mentioned that it's triggered on every browser-event. But I've noticed, that the view is even updated, when I update the bindings in an async success-handler, angular2 isn't aware of. As I don't use observables this seems quite magic to me ...

Manfred Steyer • 9 years ago

I've found the answer to my question: zone.js creates hooks for events ...

NG-newbie • 9 years ago

Could you point to the code where this happens? I was also asking myself similar question.

Manfred Steyer • 9 years ago

Sure. Have a look here: https://github.com/btford/z...
Zone.js rewrites the properties of JavaScript-prototypes to get notified, when an event happens ...

seba • 9 years ago

So, how does it differ from React? It looks to be almost the same now... Well, except they've invented their own language now, Hooray :( Sure you can do it in plain JS, but then you end up with the same mess as in Angular 1. Moving stuff out of your api and into annotations, doesn't make your api better.

It seems angular 2 will loose a huge amount of convenience for the developer in trade for performance, while the angular folks been preaching angular 1 didn't have a performance problem because you never need to show more than 2000 bound items at once etc. And to be honest, angular 1 is performing just fine and I'd rather keep my speed of development than get performance I don't need. If people need it, let them use React. Now we seem to loose the choice and get 2 times React.

Manfred Steyer • 9 years ago

While I see this point just like you, I hope, that there will be some syntax sugar, that will bring back the convenience from 1.x to 2.x ...

Jimmy Breck-McKye • 9 years ago

Forgive me, but didn't Knockout.js effectively implement this four years ago?

Victor Savkin • 9 years ago

If you are referring to the notion of Observables, then, yes, most frameworks support observable models. Most frameworks, however, require you to use a particular kind of observables and suffer from cascading updates.

Angular does not force you to use one kind of observables: you can use rxjs, object.observe, backbone models, probably even knockout models. It can take advantage of any of them because the described mechanism is more generic.

The most important thing is that you don't have to use observables at all and instead take advantage of immutable objects. The framework remains model agnostic.

Jimmy Breck-McKye • 9 years ago

Knockout does not require you to use observables if a model property does not mutate; it will quite happily bind plain properties - it just won't react to mutations. You can even place computed properties in front of multiple observables, and Knockout will only update the computed's subscribers when the computed's result actually changes.

Knockout provides a great deal of fine control over how mutation propagates; the utils it provides make it easy to write performant code naively. I think it's a real shame that so many developers dismiss it without even looking at it.

John Papa • 9 years ago

This is an important statement here: "The most important thing is that you don't have to use observables at all and instead take advantage of immutable objects."

One of the biggest draws to Angular 1.x was the idea of not requiring an implementation of wrapping objects with observability. We could use raw javascript objects. Anyone who has done this in Knockout or other similar observable tech (IObservable in .NET even) knows the cost of it is you always have to convert your objects (or wrap them) with this feature. Can you clarify your statement here on how immutable objects can be used, say, given a todo:

[
{ id: 1, description: 'go shopping'},
{id: 2, description: 'take kids to school'}
]

Victor Savkin • 9 years ago

There are three problems with using immutable objects in Angular 1.x:
- Angular does not know that they are immutable and keeps checking them. So it is not efficient.
- Custom immutable collections do not work with NgRepeat out of the box .
- NgModel does not play nicely with immutable objects.

Angular2 solves all of them.

- The change detection gives you a mechanism to express that the component depends only on immutable objects and, therefore, should not be checked until one of the bindings gets updated, as follows:

// There will be a way to express it declaratively
class ImmutableTodoCmp {
todo:Todo;
constructor(private bingings:BindingPropagationConfig){}
onChange(_) => bingings.shouldBePropagated();
}

- The change detection is pluggable, so you can teach it to detect changes in any collection.
- The new Forms API is immutable object friendly.

In Angular2 using immutable objects feels natural. You can pass an immutable collection to a repeater.

<todo !foreach="var t in todos" [todo]="t">

Use an immutable object in your template

{{todo.description}}

Even though Angular2 "just works", you will have to change the way your app is architected if you make most of your models immutable. This is not Angular specific. This will be true in any framework. That is why there are such things as Flux and Cursors (https://github.com/omcljs/o....

John Papa • 9 years ago

It appears that json objects will have to be converted to an object of this type and cannot be used as is. Unless I misunderstand. Right?

We may gain Perf but we lose something big there.

Victor Savkin • 9 years ago

Sorry, I was not clear. We can define Todo in TypeScript as follows:

interface Todo {
description:string;
checked:boolean;
}

So Todo just defines the shape of the object. It can be a regular JSON object with the two fields.

Sekib Omazic • 9 years ago

Will A2 apply DOM changes all at once (batch update) like ReactJS? I couldn't find something like "task queue" in the code base.

Victor Savkin • 9 years ago

Yes. DOM updates will be applied at once.

Sekib Omazic • 9 years ago

Cool. Looking forward to your next blog post.

It seems it's safe to conclude that Angular apps are not written anymore in JavaScript, but in Angular language. Probably this will never make it popular.

NG2 rulez • 9 years ago

It is written in TypeScript (https://twitter.com/ngconf/...