问题
I've come across an interaction between the Angular2 router and the Material Design Lite (MDL) animations. If I create an <input>
element in a component that is rendered by the <router-outlet>
component in Angular2, MDL doesn't properly handle my interactions with it (doesn't show focus animation, doesn't clear placeholder text, etc). If, on the other hand, the <input>
appears outside the <router-outlet>
, there is no problem.
It seems like it has something to do with the dynamic nature of the contents of <router-outlet>
. I thought this would solve the issue. I added an ngAfterViewInit
and ngAfterViewChecked
handler to my application (and even to my custom directive that extends RouterOutlet
). No luck. I can see the componentHandler
variable and call the updateDom
method...no problem. But it has no effect.
There must be some way to get MDL to "see" these dynamically created elements, but my attempts with upgradeDom
haven't been working. Maybe upgradeDom
isn't the problem...but then what is.
Any suggestions?
回答1:
So after further digging, I thought I had found a solution. Playing with the plunkr I was able to show that the right manual call to componentHandler.<something>
could address a similar issue I had managed to contrive in that plunkr.
However, the approach there (of creating a custom directive that triggered those calls on lifecycle events that the directive was attached to) didn't solve my issue. The "dynamic" nature of the router-outlet
was still interfering. As far as I can tell, the calls to componentHandler
were still premature and being done before the DOM had truly been updated by the router-outlet
.
What I eventually had to do was to add some code to the activate
method of RouterOutlet
. I was already creating a custom RouterOutlet
class, so it was simple enough to stick the code in the activate
method.
However, I found that is is essential that you wait until the Promise
associated with the activate
method is resolved. So I did something like this:
declare var componentHandler: any;
...
export class MyRouterOutlet extends RouterOutlet {
...
activate(instruction: ComponentInstruction) {
// My custom activate stuff (i.e., check that user is
// authorized to view this content)
// Important part, call base class...
return super.activate(instruction)
.then((x) => {
componentHandler.upgradeDom();
return x;
});
}
}
Update:
I have not confirmed it, but I suspect that the reason the other solutions I alluded to did not work was because of another issue I ran across. My suspicion is that addressing that issue properly would have allowed the other solutions I referenced here to work.
来源:https://stackoverflow.com/questions/36162649/angular2-router-interacting-with-material-design-lite