0

I am using change detection in Angular 2 to watch for changed in a deep level array. Please see this plunker...

http://plnkr.co/edit/zcl9pT?p=preview

Is there anyway to do what I am doing without using changeDetectionStrategy? Its seems like overkill having to inject it in the parent component. I really only need it for the directive that loops through the list of selected filters.

 @Component({
  selector: 'hello-world',
  templateUrl: 'src/hello_world.html',
  providers: [MyService],
  pipes: [keyValueFilterPipe, ValuesPipe, AsyncPipe],
  directives: [MyDirective, MyDirective2],
  changeDetection: ChangeDetectionStrategy.CheckAlways
})
export class HelloWorld {

    constructor(){}

  }
}
1

1 Answer 1

1

Update: this bug is fixed in beta17, as @yurzui pointed out. http://plnkr.co/edit/SwbjKn2M9NBBOYD29IML?p=preview

Related PR: https://github.com/angular/angular/commit/42231f5

It allows all legal programs in the dev mode.

The checkNoChanges function compares only primitives types for equality, and deeply compares iterables. Other objects cannot cause checkNoChanges to throw. This means that the dev mode would never fail given a legal program, but may allow some illegal programs.


Original Answer

The problem lies in your pipe's implementation. Every time keyValueFilterPipe returns a new JavaScript object, that is not the same as the last one returned by the same filter. Angular think this is a bug in your code and ceases to work.

You can see the error reported in console like ... has changed after it was checked. Not only your directive stops to work, normal text-binding also breaks.

Angular2 in dev mode will try to figure out what is changed during its "dirty check". So if a developer mistakenly puts a cyclic call in template, Angular will report that.

This is a feature in Angular2. But it harms you.

The solution is easy. Either change the detection strategy, like you do. Or call enableProd to suppress the warning. Or implement keyValueFilter that always returns a fixed object(by WeakMap e.g.)


See also

http://www.bennadel.com/blog/3040-i-have-a-fundamental-misunderstanding-of-change-detection-in-angular-2-beta-8.htm

And Angular's original issue, especially this comment

https://github.com/angular/angular/issues/5918#issuecomment-167422071

Sign up to request clarification or add additional context in comments.

5 Comments

So I changed to 17, but the problem now is that I have the click the button to remote the item twice the first time, or set focus in the area of the directive. Why? plnkr.co/edit/7iUEja
Can you explain how I could get the keyValueFilter to return a fixed object?
Please update your example. I cannot know what you mean by remove twice because that button just alerts.
I think I got it working but do not like the implementation: plnkr.co/edit/mwrD1W?p=preview I remove focus from the input when mouseenter of the other area where the buttons are.
@JudsonTerrell Using eventEmitter is a good choice in my eye :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.