Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
633 views
in Technique[技术] by (71.8m points)

angular - Angular2 Router interacting with Material Design Lite

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...