简体   繁体   中英

Error: [$compile:multidir] while binding md-sidenav with controller (angular material)

I want to create app with side menu using Angular Material. I get Error: [$compile:multidir] .

What I'm doing wrong?

Here is my index.html:

<!doctype html>
<html ng-app="myApp">
<head>
    <meta charset="utf-8">
    <link href="/css/angular-material.min.css" rel="stylesheet" />
</head>

<body>
    <div class="container" layout="row" flex>
        <md-sidenav ng-controller="leftMenuController" md-is-locked-open="true">Sidenav</md-sidenav>
        <md-content flex id="content" flex><ng-view></ng-view></md-content>
    </div>

<script src="/js/lib/angular.min.js" type="text/javascript"></script>
<script src="/js/lib/angular-animate.min.js" type="text/javascript"></script>
<script src="/js/lib/angular-aria.min.js" type="text/javascript"></script>
<script src="/js/lib/angular-sanitize.min.js" type="text/javascript"></script>
<script src="/js/lib/angular-route.min.js" type="text/javascript"></script>
<script src="/js/lib/angular-material.min.js" type="text/javascript"></script>
<script src="/js/engine.js" type="text/javascript"></script>
<script src="/js/controllers/leftMenuController.js"></script>
<script src="/js/controllers/authController.js"></script>
<script src="/js/controllers/clientsController.js"></script>

</body>
</html>

Here is my leftMenuController:

myApp.controller('leftMenuController',
    function leftMenuController($scope, $location){
        console.log("leftMenuController" + $location.url().toString());
    }
);

Here is my auth.html and authController.js:

<div ng-controller="authController">
    <md-button class="md-raised" ng-click="login()">Button</md-button>
</div>

myApp.controller('authController',
    function authController($scope, $location){
        $scope.login = function () {
            $location.path( "/clients" );
        }
    }
);

Here is my engine.js:

var myApp = angular.module('myApp', ["ngRoute", "ngMaterial"])
.config(function($routeProvider){
    $routeProvider.when('/auth',
        {
            templateUrl:'/views/auth.html',
            controller:'authController'
        });
    $routeProvider.when('/clients',
        {
            templateUrl:'/views/clients.html',
            controller:'clientsController'
        });
    $routeProvider.otherwise({redirectTo: '/auth'});
});

I'm new on Stackoverflow and this will be my first answer. I'm also new to JavaScript and Angular but as I've run into the same problem as you have, I think I have the correct answer.

The md-sidenav directive has it's own controller: https://github.com/angular/material/blob/master/src/components/sidenav/sidenav.js

The error you're getting is basically saying that you can't assign two controllers to the same scope(forgive my incorrect terminology)

Depending on what you want to do in your leftMenuController, you just have to assign it to a different element in your HTML. I'm using it to display the navigation menu options, so I assigned it to the md-list I have in my md-sidenav.

I actually created a custom directive for the sidenav (nav-menu.html):

<md-sidenav md-is-locked-open="$mdMedia('gt-sm')" md-component-id="navigation">
  <md-toolbar hide-gt-sm layout-align="center center">
    <md-button class="md-icon-button" hide-gt-sm aria-label="Settings" ng-click="TlbCtrl.toggle()">
    <span>Navigation</span>
  </md-toolbar>
  <md-list  ng-controller="NavMenuController as navCtrl">
    <md-list-item ng-repeat="nav in navCtrl.navMenu" ng-click="navCtrl.hide()" ng-href="{{nav.ref}}" target="{{nav.target}}">{{nav.name}}</md-list-item>
  </md-list>
</md-sidenav>

This is the custom directive:

(function() { 'use strict';

 angular.module('VissenKom')
 .directive('navigationMenu', function(){
    // Runs during compile
    return {
        restrict: 'E',
        templateUrl: 'components/nav-menu.html',
    };
 });
})();

This is the controller:

(function() { 'use strict';

 angular.module('VissenKom')
 .controller('NavMenuController', ['$mdSidenav', function($mdSidenav){
  // Hide after click
  this.hide = function () {
    // Only close when not locked open
    if (!$mdSidenav('navigation').isLockedOpen()){
    $mdSidenav('navigation').close();
  }
  };

  // Nav menu entries
  this.navMenu = [{
    name: 'Home',
    ref: '#/'
  },{
    name: 'Metingen',
    ref: '#/metingen'
  },{
    name: 'Vissen',
    ref: '#/vissen'
  },{
    name: 'Aquarium',
    ref: '#/aquarium'
  }];
 }]);
})();

And part of my index.html:

  <div layout="row">
    <navigation-menu></navigation-menu>
    <md-content id="content" layout-margin><ng-view></ng-view></md-content>
  </div>

I've also seen examples where the controller was attached outside the md-sidenav directive, but I'm not sure if that would work if you put the sidenav in a custom directive like I have.

I hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM