问题
I am trying to use Material design lite with an Ember.js application and got the form working somehow. However, when the user navigates from one page to another page containing the form or inputs, the inputs do not seem to behave as expected. For an example here, when the page loads first time to home page, input works fine but when we switch between sign-in and home pages, inputs fallbacks to basic form and material design animation is lost.
Not sure if this issue is related to Ember.js or Material design but any help would be highly appreciated.
回答1:
MDL requires elements to be initialized to get special effects such as buttons with ripples, or animated input boxes. They are initialized by default on page load, but elements inserted by views or components will not be initialized. The simplest approach is to initialize them on didInsertElement
.
A more general approach would be a mixin which handles this for you, as in:
// mixins/mdl-button.js
export default Ember.Mixin.create() {
initializeMdlButtons: function() {
var buttons = this.get('element').querySelectorAll('.mdl-button');
[].forEach.call(buttons, button => componentHandler.upgradeElement(button));
}.on('didInsertElement')
Then in your component using buttons
import MdlButton from 'app/mixins/mdl-button';
export default Ember.Component.extend(MdlButton, {
...
});
Or, you could apply this to all components with
Ember.Component.reopen(MdlButton);
回答2:
You will need to create handlers to initialize the required JS for each MDL component. You have two possibilities:
- Use the JavaScript that comes with MDL, though it will become toublesome on some of the components.
- Implement JS on your own per component, and use ideas of the JS internally in MDL.
I used 2. This is why I have written a ember-addon specifically to create ember components out of MDL.
It's pretty simple.
ember install ember-mdl
Demo / docs: http://peec.github.io/ember-mdl/
Example of implementation is in the dummy app
回答3:
Or you can just do componentHandler.upgradeDom() on didInsertElement. Which based on their documentation
Searches existing DOM for elements of our component type and upgrades them * if they have not already been upgraded.
initializeItems: function () {
componentHandler.upgradeDom();
}.on('didInsertElement')
回答4:
Thanks @torazaburo for your suggestation. I had to modify mixin to get it working. In my case i have textfield input and needed to modify the mixing. Here is my solution if someone still needs.
// app/mixins/textfield-support.js
import Ember from 'ember';
export default Ember.Mixin.create({
initializeMdlTextfield: function() {
componentHandler.upgradeElement(this.get('element'), 'MaterialTextfield');
}.on('didInsertElement')
});
Then we can extend the mixing in our component as below.
// app/components/mdl-textfield-input.js
import Ember from 'ember';
import layout from '../templates/components/mdl-textfield-input';
import mdlTextfield from '../mixins/textfield-support';
export default Ember.Component.extend(mdlTextfield, {
tagName : 'div',
attributeBindings : ['disabled', 'type', 'name' ],
hasFloatingLabel : false,
containerClassNames : '',
labelText : null,
classNames : ['mdl-textfield', 'mdl-js-textfield'],
classNameBindings: [
'hasFloatingLabel:mdl-textfield--floating-label',
'containerClassNames'
],
layout
});
Component template would look something like this.
// app/templates/components/mdl-textfield-input.hbs
{{yield}}
{{input id=name value=value type=type disabled=disable classNames="mdl-textfield__input"}}
<label class="mdl-textfield__label" for={{name}}>{{labelText}}</label>
<span class="mdl-textfield__error">{{error}}</span>
And use this component as below.
{{mdl-textfield-input
name='username'
value=model.username
labelText='Username'
hasFloatingLabel=true
type='text'
containerClassNames ='mdl-cell--12-col'
}}
来源:https://stackoverflow.com/questions/31492069/material-design-lite-inputs-in-ember-js-app-loses-it-design-after-route-transiti