<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Angular + MaterializeCSS</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/css/materialize.min.css">
    <link rel="stylesheet" href="style.css">
</head>

<body ng-app="mainApp">

    <header>
        <nav class="teal" role="navigation">
            <div class="nav-wrapper container"><a id="logo-container" href="#!/" class="brand-logo right"><i class="material-icons">fingerprint</i></a>
                <ul id="main-menu" class="left hide-on-med-and-down">
                    <li><a href="#!/" class="waves-effect waves-teal"><i class="material-icons left">home</i>Home</a></li>
                    <li><a href="#!/items" class="waves-effect waves-teal"><i class="material-icons left">list</i>Items</a></li>
                    <li><a href="#!/profile" class="waves-effect waves-teal"><i class="material-icons left">person</i>Profile</a></li>
                    <li><a href="#!/settings" class="waves-effect waves-teal"><i class="material-icons left">settings</i>Settings</a></li>
                </ul>
                <ul id="main-menu-mobile" class="side-nav">
                    <!-- look at script.js -->
                </ul>
                <a href="javascript:void(0)" data-activates="main-menu-mobile" class="button-collapse"><i class="material-icons">menu</i></a>
            </div>
        </nav>

        <div class="progress teal lighten-4" ng-show="ajaxConnections">
            <div class="indeterminate"></div>
        </div>
    </header>

    <main class="container">
        <div ng-view></div>
    </main>

    <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-route.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/js/materialize.min.js"></script>
    <script type="text/javascript" src="script.js"></script>
    <script type="text/javascript" src="app.js"></script>

</body>

</html>
/**
 * Materialize CSS needs the top menu twice (one for mobile and another one for desktop)
 * This clones the whole menu and adds it to mobile one (it doesn't yet work for dropdowns)
 */
$('#main-menu li').each(function(){
   $('#main-menu-mobile').append($(this).clone(true)); 
});

/**
 * Materialize needs the hamburger button to be told what to do
 */
$('nav .button-collapse').sideNav({
    closeOnClick: true
});

/**
 * Initialize the date picker every time such a field comes into view
 */
function initDatePicker(){
    $('.datepicker').each(function(){
        $(this).data('value', this.value);
    }).pickadate({
        selectMonths: true, // Creates a dropdown to control month
        selectYears: 80, // Creates a dropdown of 80 years to control year
        closeOnSelect: true,
        format: 'dd mmmm yyyy',
        formatSubmit: 'yyyy-mm-dd',
    });
}
header .progress{
    position: fixed;
    bottom: 0;
    margin: 0;
    z-index: 99;
}

table.editables textarea{
    height: 16px;
}
An example of Materialize CSS working with AngularJS.

For now it only has paragraphs, table and form. Datepicker, autocomplete and more such awsome features to be implemented soon.

TODO: add the missing features (item details and profile page)
var mainApp = angular.module('mainApp', ['ngRoute']);

/**
 * Route configuration
 */
mainApp.config(function($routeProvider, $locationProvider, $httpProvider) {
    $locationProvider.hashPrefix('!');
    $httpProvider.interceptors.push('ajaxLoading');
    $routeProvider
        .when('/', {
            templateUrl: 'home.html',
            controller: 'HomeController'
        })
        .when('/items', {
            templateUrl: 'items.html',
            controller: 'ItemsController'
        })
        .when('/items/:itemId', {
            template: '<div class="item_details">item-details for {{ itemId }}</div>',
            controller: 'ItemDetailsController'
        })
        .when('/profile', {
            templateUrl: 'profile.html',
            controller: 'ProfileController'
        })
        .when('/settings', {
            templateUrl: 'settings.html',
            controller: 'SettingsController'
        });
});

/**
 * Capture any AJAX loading
 */
mainApp.factory('ajaxLoading', function($q, $rootScope) {
    return {
        request: function(config) {
            $rootScope.ajaxConnections ? $rootScope.ajaxConnections++ : $rootScope.ajaxConnections = 1;
            return config;
        },
        response: function(response) {
            $rootScope.ajaxConnections--;
            return response;
        },
        requestError: function(config) {
            $rootScope.ajaxConnections--;
            return $q.reject(config);
        },
        responseError: function(response) {
            Materialize.toast(response.config.method + ' request to ' + response.config.url + ' was refused with status ' + response.status, 5000);
            $rootScope.ajaxConnections--;
            return $q.reject(response);
        }
    };
});

/**
 * HomeController doesn't do anything really
 */
mainApp.controller('HomeController', function($scope) {
    // console.debug('HomeController');
});

/**
 * ItemsController loads the JSON containing the items
 */
mainApp.controller('ItemsController', function($scope, $http) {
    $scope.items = [];
    // This object holds the item currently being edited
    $scope.editing = {};

    $http.get('items.json', {
        cache: false
    }).then(function(response) {
        $scope.items = response.data;
    });
    
    $scope.edit = function(item){
        $scope.editing = item;
    }
    
});

mainApp.controller('ItemDetailsController', function($scope) {
    //alert('ItemDetailsController');
});
mainApp.controller('ProfileController', function($scope, $http, $timeout) {
    $scope.autoSave = true;
    $scope.user = {};
    $scope.toast = null;
    
    /**
     * Called after every ajax request made by this controller, should receive the settings object every time
     */
    $scope.loadProfile = function(response) {
        $scope.user = response.data;
        if ($scope.toast) {
            Materialize.toast($scope.toast, 1000);
            $scope.toast = null;
        }
        $timeout(initDatePicker);
        $timeout(Materialize.updateTextFields);
    }

    /**
     * POST the current $scope.user to the server and waits for the same object to return
     */
    $scope.saveForm = function(auto) {
        if (!auto || auto && $scope.autoSave) {
            $scope.toast = 'The profile has been saved';
            $http.post('profile.json', $scope.user).then($scope.loadProfile);
        }
    }
    
    /**
     * Load the settings every time this controller is invoked (every time the user clicks 'Settings')
     */
    $http.get('profile.json', {
        cache: false
    }).then($scope.loadProfile);

});

/**
 * SettingsController loads the settings and links the form with $scope.settings
 */
mainApp.controller('SettingsController', function($scope, $http, $timeout) {
    $scope.autoSave = true;
    $scope.settings = {};
    $scope.toast = null;
    
    /**
     * Called after every ajax request made by this controller, should receive the settings object every time
     */
    $scope.loadSettings = function(response) {
        $scope.settings = response.data;
        if ($scope.toast) {
            Materialize.toast($scope.toast, 1000);
            $scope.toast = null;
        }
        $timeout(Materialize.updateTextFields);
    }

    /**
     * POST the current $scope.settings to the server and waits for the same object to return
     */
    $scope.saveForm = function(auto) {
        if (!auto || auto && $scope.autoSave) {
            $scope.toast = 'Settings have been saved';
            $http.post('settings.json', $scope.settings).then($scope.loadSettings);
        }
    }
    
    /**
     * Load the settings every time this controller is invoked (every time the user clicks 'Settings')
     */
    $http.get('settings.json', {
        cache: false
    }).then($scope.loadSettings);

});
<div class="col s12">
    <h1>Settings</h1>
</div>

<form class="row" name="settingsForm">
    <div class="col s12">
        <div class="input-field">
            <input type="text" id="name" class="validate" required="" ng-model="settings.name" ng-model-options="{updateOn: 'blur'}" ng-change="saveForm(true)">
            <label for="name" data-error="wrong">Project Name</label>
        </div>
        <div class="input-field">
            <input type="url" id="url" class="validate" ng-model="settings.url" ng-model-options="{updateOn: 'blur'}" ng-change="saveForm(true)">
            <label for="url" data-error="wrong">Project URL</label>
        </div>
        <div class="input-field">
            <input type="number" id="number_items" class="validate" required="" ng-model="settings.number_items" ng-model-options="{updateOn: 'blur'}" ng-change="saveForm(true)">
            <label for="number_items">Number of Items per Page</label>
        </div>
        <div class="input-field">
            <input type="email" id="email" class="validate" required="" ng-model="settings.email" ng-model-options="{updateOn: 'blur'}" ng-change="saveForm(true)">
            <label for="email" data-error="wrong">Contact Email</label>
        </div>
        <div class="input-field">
            <input type="tel" id="phone" class="validate" ng-model="settings.phone" ng-model-options="{updateOn: 'blur'}" ng-change="saveForm(true)">
            <label for="phone">Contact Phone</label>
        </div>
        <div class="input-field">
            <textarea id="description" class="materialize-textarea" ng-model="settings.description" ng-model-options="{updateOn: 'blur'}" ng-change="saveForm(true)"></textarea>
            <label for="description">Short Project Description</label>
        </div>
        <div>
            <input type="checkbox" id="beta" class="filled-in" ng-model="settings.beta" ng-click="saveForm(true)">
            <label for="beta">Project is in BETA</label>
        </div>
    </div>
    <div class="col m6">
        <div class="input-field">
            <button type="submit" class="btn btn-large waves-effect waves-light" ng-disabled="ajaxConnections" ng-click="saveForm()">
                <i class="material-icons right">save</i> Save Settings
            </button>
        </div>
    </div>
    <div class="col m6">
        <div class="input-field">
            <input type="checkbox" id="autosave" class="filled-in" ng-model="autoSave">
            <label for="autosave">Auto Save Form</label>
        </div>
    </div>
</form>
{
    "name": "A Work in Progress",
    "url": "http://localhost",
    "number_items": 25,
    "email": "office@localhost",
    "phone": "Just a test",
    "beta": true,
    "description": "This is just a proof of concept;\nWill try to add as much examples as I can, but I'm already bored"
}
<div class="row">
    <div class="col s12">
        <h1>Welcome</h1>
    </div>
    <p class="col s12 flow-text">Bacon ipsum dolor amet magna venison meatloaf, tempor salami short loin tail boudin in filet mignon cillum minim et cow. Hamburger kevin eu labore ipsum occaecat tongue swine laborum landjaeger tail biltong flank pork loin ball tip. In pork loin non
        proident sunt picanha. Jerky est beef turducken in pork shankle consectetur sed lorem officia leberkas. Bresaola flank in deserunt laborum. Cillum strip steak irure, nostrud qui ribeye consectetur tongue esse labore tail dolor. Kielbasa pariatur
        brisket spare ribs, voluptate quis fugiat porchetta.</p>

    <p class="col s12 flow-text">Venison frankfurter cillum ut sint meatloaf laboris pariatur nisi aute in est doner. In kielbasa ut shankle jowl, bacon anim enim dolore adipisicing turducken. Hamburger venison tri-tip jerky sunt pork belly aliqua aute ea fugiat nostrud drumstick.
        Kevin biltong cow dolore, strip steak labore t-bone chicken veniam pariatur jerky venison sunt capicola. Aute salami short loin biltong boudin t-bone tenderloin do anim hamburger ham hock jerky quis ground round. Enim exercitation ad, est leberkas
        ipsum id deserunt cillum chicken bresaola in.</p>

    <p class="col s12 flow-text">Sunt ground round in swine shank jerky. Kielbasa pork loin pork picanha. Ullamco pancetta porchetta pig in, non adipisicing short loin ham hock. Reprehenderit bacon in exercitation turkey tail fugiat. Leberkas deserunt tongue alcatra chuck qui jowl.</p>

    <p class="col s12 flow-text">Tenderloin boudin in, beef venison eu incididunt ex kielbasa ground round. Esse landjaeger kielbasa, sausage pariatur consectetur pancetta. Shankle short ribs biltong nostrud, ut enim tempor chicken ham hock shoulder corned beef commodo veniam porchetta
        hamburger. Sint ham hock biltong jowl venison esse sed veniam. Occaecat brisket andouille consequat laborum jerky, ground round salami short ribs hamburger pork chop pork. Tempor shank corned beef ut pork loin strip steak picanha voluptate ham
        esse excepteur.</p>

    <p class="col s12 flow-text">Qui veniam do fugiat anim, eu pig corned beef ipsum pork chop hamburger porchetta ground round dolor. Venison dolore aliqua, picanha voluptate consequat ut beef ribs beef turducken ipsum excepteur rump ball tip qui. Est meatloaf prosciutto, picanha
        meatball irure turducken shankle lorem sirloin aliquip jowl cupidatat nisi. Kielbasa boudin cupidatat frankfurter excepteur incididunt leberkas dolor. Beef fatback pastrami, in nostrud tempor capicola anim sirloin aliquip sunt cow.</p>
</div>
[{
  "id": 1,
  "name": "Bitchip",
  "last_version": "3.2",
  "active": true,
  "tag": "Pre-emptive demand-driven internet solution",
  "publisher": "Voonder",
  "created_at": "2015-10-19T09:08:05Z",
  "updated_at": "2016-04-22T13:54:05Z"
}, {
  "id": 2,
  "name": "Ronstring",
  "last_version": "6.7",
  "active": false,
  "tag": "Synergized optimal website",
  "publisher": "Abata",
  "created_at": "2015-11-18T12:34:40Z",
  "updated_at": "2016-03-31T09:11:43Z"
}, {
  "id": 3,
  "name": "Redhold",
  "last_version": "0.39",
  "active": true,
  "tag": "Focused explicit encryption",
  "publisher": "Topiczoom",
  "created_at": "2016-03-23T23:50:05Z",
  "updated_at": "2016-03-22T01:25:06Z"
}, {
  "id": 4,
  "name": "Toughjoyfax",
  "last_version": "8.91",
  "active": false,
  "tag": "Diverse intangible architecture",
  "publisher": "Browsecat",
  "created_at": "2015-11-16T15:56:16Z",
  "updated_at": "2016-09-10T10:58:42Z"
}, {
  "id": 5,
  "name": "Zamit",
  "last_version": "8.33",
  "active": true,
  "tag": "Multi-layered bifurcated array",
  "publisher": "Voolith",
  "created_at": "2016-01-08T22:24:36Z",
  "updated_at": "2016-03-08T04:37:01Z"
}, {
  "id": 6,
  "name": "Span",
  "last_version": "7.66",
  "active": false,
  "tag": "Total 4th generation migration",
  "publisher": "Meevee",
  "created_at": "2016-07-25T00:56:48Z",
  "updated_at": "2016-04-20T06:07:17Z"
}, {
  "id": 7,
  "name": "Konklab",
  "last_version": "0.5.9",
  "active": true,
  "tag": "Enterprise-wide responsive challenge",
  "publisher": "Gabspot",
  "created_at": "2015-12-15T16:52:46Z",
  "updated_at": "2015-12-14T04:23:28Z"
}, {
  "id": 8,
  "name": "Rank",
  "last_version": "4.13",
  "active": true,
  "tag": "Fundamental even-keeled implementation",
  "publisher": "Einti",
  "created_at": "2016-07-13T00:44:32Z",
  "updated_at": "2016-08-08T06:21:09Z"
}, {
  "id": 9,
  "name": "Tin",
  "last_version": "2.1.8",
  "active": false,
  "tag": "Business-focused disintermediate knowledge user",
  "publisher": "Twitterbridge",
  "created_at": "2015-11-06T12:44:54Z",
  "updated_at": "2016-02-25T11:04:57Z"
}, {
  "id": 10,
  "name": "Span",
  "last_version": "0.2.7",
  "active": false,
  "tag": "Adaptive foreground toolset",
  "publisher": "Eidel",
  "created_at": "2016-03-23T14:05:56Z",
  "updated_at": "2016-03-29T09:11:13Z"
}, {
  "id": 11,
  "name": "Sonsing",
  "last_version": "0.5.2",
  "active": false,
  "tag": "Decentralized explicit standardization",
  "publisher": "Zoombeat",
  "created_at": "2016-03-26T21:25:40Z",
  "updated_at": "2016-02-09T08:37:59Z"
}, {
  "id": 12,
  "name": "Bytecard",
  "last_version": "3.67",
  "active": true,
  "tag": "Function-based coherent utilisation",
  "publisher": "Centidel",
  "created_at": "2016-04-29T06:10:09Z",
  "updated_at": "2016-07-30T12:10:18Z"
}, {
  "id": 13,
  "name": "Stim",
  "last_version": "7.65",
  "active": false,
  "tag": "Managed real-time framework",
  "publisher": "Devify",
  "created_at": "2016-04-25T15:26:01Z",
  "updated_at": "2016-02-15T12:45:16Z"
}, {
  "id": 14,
  "name": "Solarbreeze",
  "last_version": "0.3.6",
  "active": false,
  "tag": "Operative static superstructure",
  "publisher": "Dabtype",
  "created_at": "2016-02-11T04:29:20Z",
  "updated_at": "2015-12-17T11:58:57Z"
}, {
  "id": 15,
  "name": "Regrant",
  "last_version": "0.4.9",
  "active": true,
  "tag": "Multi-layered interactive archive",
  "publisher": "Dabfeed",
  "created_at": "2016-03-23T05:33:39Z",
  "updated_at": "2016-05-15T19:20:08Z"
}, {
  "id": 16,
  "name": "Cardguard",
  "last_version": "0.4.8",
  "active": false,
  "tag": "Assimilated optimal internet solution",
  "publisher": "Katz",
  "created_at": "2015-12-17T18:33:35Z",
  "updated_at": "2016-09-08T08:19:23Z"
}, {
  "id": 17,
  "name": "Span",
  "last_version": "3.3",
  "active": true,
  "tag": "Compatible even-keeled flexibility",
  "publisher": "Devshare",
  "created_at": "2016-08-30T06:26:20Z",
  "updated_at": "2015-11-14T03:54:01Z"
}, {
  "id": 18,
  "name": "Lotlux",
  "last_version": "9.7.1",
  "active": true,
  "tag": "Multi-lateral zero defect contingency",
  "publisher": "Eimbee",
  "created_at": "2016-04-22T13:28:05Z",
  "updated_at": "2016-04-09T23:53:54Z"
}, {
  "id": 19,
  "name": "Sonair",
  "last_version": "0.8.2",
  "active": true,
  "tag": "Robust grid-enabled task-force",
  "publisher": "Gabcube",
  "created_at": "2016-08-25T02:21:51Z",
  "updated_at": "2016-06-29T14:54:58Z"
}, {
  "id": 20,
  "name": "Greenlam",
  "last_version": "0.96",
  "active": false,
  "tag": "Adaptive actuating website",
  "publisher": "Jatri",
  "created_at": "2016-01-17T14:27:16Z",
  "updated_at": "2016-04-21T02:27:44Z"
}]
<div class="col s12">
    <h1>Items</h1>
    <p>Double click to edit the row.</p>
</div>

<table class="highlight editables">
    <thead>
        <tr>
            <th>ID</th>
            <th>Publisher</th>
            <th>Name</th>
            <th>Version</th>
            <th>Tag</th>
            <th>Active</th>
            <th>&nbsp;</th>
        </tr>
    </thead>
    <tbody ng-repeat="item in items">
        <tr ng-show="editing != item" ng-dblclick="edit(item)">
            <td>{{ item.id }}</td>
            <td>{{ item.publisher }}</td>
            <td>{{ item.name }}</td>
            <td>{{ item.last_version }}</td>
            <td>{{ item.tag }}</td>
            <td><i class="material-icons">{{ item.active ? 'done' : 'clear' }}</i></td>
            <td><a href="#!/items/{{ item.id }}" class="badge waves-effect waves-light"><i class="material-icons">arrow_forward</i></a></td>
        </tr>
        <tr ng-show="editing == item">
            <td>{{ item.id }}</td>
            <td><input type="text" ng-model="item.publisher"></td>
            <td><input type="text" ng-model="item.name"></td>
            <td><input type="text" ng-model="item.last_version"></td>
            <td>
                <div class="input-field col s12">
                    <textarea class="materialize-textarea" ng-model="item.tag"></textarea>
                </div>
            </td>
            <td><input type="checkbox" id="active{{ item.id }}" ng-model="item.active"><label for="active{{ item.id }}"></label></td>
            <td><a href="#!/items/{{ item.id }}" class="badge waves-effect waves-light"><i class="material-icons">save</i></a></td>
        </tr>
    </tbody>
</table>
<div class="col s12">
    <h1>Profile</h1>
</div>

<form class="row" name="userForm">
    <div class="col m6">
        <div class="input-field">
            <input type="text" id="first_name" class="validate" required="" ng-model="user.first_name" ng-model-options="{updateOn: 'blur'}" ng-change="saveForm(true)">
            <label for="first_name" data-error="wrong">First Name</label>
        </div>
    </div>
    <div class="col m6">
        <div class="input-field">
            <input type="text" id="last_name" class="validate" required="" ng-model="user.last_name" ng-model-options="{updateOn: 'blur'}" ng-change="saveForm(true)">
            <label for="last_name" data-error="wrong">Last Name</label>
        </div>
    </div>
    <div class="col s12">
        <div class="input-field">
            <input type="email" id="email" class="validate" required="" ng-model="user.email" ng-model-options="{updateOn: 'blur'}" ng-change="saveForm(true)">
            <label for="email" data-error="wrong">Email</label>
        </div>
        <div class="input-field">
            <input type="text" id="birthdate" class="datepicker" required="" ng-model="user.birthdate" ng-model-options="{updateOn: 'blur'}" ng-change="saveForm(true)">
            <label for="birthdate">Birth Date</label>
        </div>
        <div>
            <input type="checkbox" id="agree" class="filled-in" ng-model="user.agree" ng-click="saveForm(true)">
            <label for="agree">Agree</label>
        </div>
    </div>
    <div class="col m6">
        <div class="input-field">
            <button type="submit" class="btn btn-large waves-effect waves-light" ng-disabled="ajaxLoadingFlag" ng-click="saveForm()">
                <i class="material-icons right">save</i> Save Profile
            </button>
        </div>
    </div>
    <div class="col m6">
        <div class="input-field">
            <input type="checkbox" id="autosave" class="filled-in" ng-model="autoSave">
            <label for="autosave">Auto Save Form</label>
        </div>
    </div>
</form>
{
    "id": 101,
    "first_name": "John",
    "last_name": "Doe",
    "email": "john.doe@example.com",
    "birthdate": "1989-12-22",
    "agree": false
}