Using materializecss with aurelia

2020-03-05 03:57发布

问题:

I would like to ask if there's a step by step way to use or configure materializecss with Aurelia. I'm currently able to run my Aurelia app up to the point in the tutorials where my index.html looks like this:

<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8" />
   <link href="jspm_packages/github/dogfalo/materialize@0.97.0/dist/css/materialize.css" rel="stylesheet" />
   <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
   <title></title>
</head>
<body aurelia-app>
   <script src="jspm_packages/system.js"></script>
   <script src="config.js"></script>
   <script>
      System.import('aurelia-bootstrapper');
   </script>
</body>
</html>

I'm currently using the ASP .NET 5 Preview empty template and jspm to install Aurelia. I have installed materializecss withjspm install github:dogfalo/materialize and copied some html code from this link to test if it works.

This code went into my app.html file

<template>
<ul class="collapsible" data-collapsible="accordion">
    <li>
        <div class="collapsible-header"><i class="material-icons">filter_drama</i>First</div>
        <div class="collapsible-body"><p>Lorem ipsum dolor sit amet.</p></div>
    </li>
    <li>
        <div class="collapsible-header"><i class="material-icons">place</i>Second</div>
        <div class="collapsible-body"><p>Lorem ipsum dolor sit amet.</p></div>
    </li>
    <li>
        <div class="collapsible-header"><i class="material-icons">whatshot</i>Third</div>
        <div class="collapsible-body"><p>Lorem ipsum dolor sit amet.</p></div>
    </li>
</ul>
</template>

while my app.html file has this for the test

export class App {
    constructor() {
       this.message = 'test app';
    }
}

and my package.json currently contains these

{
 "jspm": {
   "directories": {
   "baseURL": "wwwroot"
 },
 "dependencies": {
   "aurelia-bootstrapper": "github:aurelia/bootstrapper@^0.16.0",
   "aurelia-framework": "github:aurelia/framework@^0.15.0",
   "dogfalo/materialize": "github:dogfalo/materialize@^0.97.0"
 },
 "devDependencies": {
   "babel": "npm:babel-core@^5.8.22",
   "babel-runtime": "npm:babel-runtime@^5.8.20",
   "core-js": "npm:core-js@^1.1.0"
  }
 }
}

When I browse the index.html file in Chrome, I can see the nicely formatted collapsible but when I click on any of the headers the body would not expand. It seems that the js file is not referenced or was not configured correctly by jspm.

回答1:

You're almost there- the materialize library has a javascript component that enables some of the features. In the documentation for the collapsible component there's this:

Initialization

Collapsible elements only need initialization if they are added dynamically. You can also pass in options inside the initialization, however this can be done in the HTML markup as well.

$(document).ready(function(){
    $('.collapsible').collapsible({
      accordion : false // A setting that changes the collapsible behavior to expandable instead of the default accordion style
    });
  });

These instructions are useful for static pages but not helpful with single-page-apps like yours. You can't use $(document).ready because your the component isn't on the page when that event fires.

The simplest thing you can do to get the component working is to give the view-model a reference to the collapsible element and then call $(element).collapsible() on it. Here's how to do that...

First, add the ref attribute to the ul:

<template>
<ul ref="myElement" class="collapsible" data-collapsible="accordion">
    <li>
        <div class="collapsible-header"><i class="material-icons">filter_drama</i>First</div>
        <div class="collapsible-body"><p>Lorem ipsum dolor sit amet.</p></div>
    </li>
    <li>
        <div class="collapsible-header"><i class="material-icons">place</i>Second</div>
        <div class="collapsible-body"><p>Lorem ipsum dolor sit amet.</p></div>
    </li>
    <li>
        <div class="collapsible-header"><i class="material-icons">whatshot</i>Third</div>
        <div class="collapsible-body"><p>Lorem ipsum dolor sit amet.</p></div>
    </li>
</ul>
</template>

Next, initialize the collapsible when the element is attached to the DOM:

export class App {
    constructor() {
       this.message = 'test app';
    }
    attached() {
       $(this.myElement).collapsible();
    }
}

Finally, make sure the materializecss jquery components are loaded by adding the following line to your app.js:

import materialize from 'dogfalo/materialize';

All this could get tedious if you're dealing with a lot of views or elements, so you'll want to wrap this logic up in an aurelia custom attribute to make things more convenient:

import {inject} from 'aurelia-framework';

@inject(Element)
export class CollapsibleCustomAttribute {
  constructor(element) {
    this.element = element;
  }

  attached() {
    ${this.element).collapsible();
  }
}

Now you can simply add the collapsible attribute to your element and it will initialize the materializecss's behavior automatically.



回答2:

Since I only want some specific features of materializecss I did it by copying the materialize files into my style folders stlye/scss, style/js style/font. The structure is like

src/
    index.html
    config.js
    app/
        app.js
        …
    style/
        font/
        js/
        images/
        scss/

In my index.html I'm loading only that js files I really want.

<script>
    System.import('aurelia-bootstrapper');
    System.import('jquery').then(function() {
        window.Materialize = {};
        System.import('style/js/forms');
        System.import('style/js/waves');
        System.import('style/js/jquery.easing.1.3');
        System.import('style/js/velocity.min');
        System.import('style/js/hammer.min').then(function() {
            System.import('style/js/jquery.hammer');
        });
    });
</script>

In my main scss file I'm also including only the style files I really need. You also could install it with jspm install github:dogfalo/materialize and load it in index.html with System.import('dogfalo/materialize')

Hope it helpes you to find your way :)