2016-11-24 3 views
0

Ich bin ziemlich neu in Angular.js und versuche, es in meiner Node.js App zu implementieren.Verwenden mehrerer Angular.js Controller auf demselben DOM

Ich hatte Erfolg beim Erstellen einer RESTful-API mit angular für einen einzelnen Controller, möchte aber jetzt zwei oder mehr Controller auf einem einzelnen DOM verwenden.

Insbesondere würde Ich mag an ..

1) Winkel Verwenden Sie einen globalen Rahmen für die DOM-Vorlage zu laden Dinge wie Site-Titel, Navigation enthält, und Metadaten, von denen alle in den Kopf geladen wird, Kopf-und Fußzeile. Der Geltungsbereich würde mit einer GET-Anforderung an meinen Node-Server abgerufen werden.

2) Verwenden Sie angular, um den Bereich für eine bestimmte Seite zu laden. Dies würde von Fall zu Fall für jede Seite gelten. Der einfache Fall ist, den Bereich in die Vorlage zu laden.

Es ist mir gelungen, sowohl (1) als auch (2) einzeln zu machen, aber das Kombinieren von ihnen wirft einen Fehler.

Hier ist meine komplette Vorlage (tatsächlich in Teilen von Knoten geladen):

Head - enthält ng-Controller = "configCtrl" scope für die globale Konfiguration

<html ng-app="angular" ng-controller="configCtrl" ><head> 

<meta http-equiv="Content-Type" content="text/html charset=UTF-8" /> 
<title>{{context.title}}</title> 
<meta name="description" content="{{context.description}}"> 
<meta name="author" content="{{context.author}}"> 

<!-- Angular --> 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script> 

</head><body><div id="wrapper" > 

Body - enthält ng-controller = "testCtrl" für diesen bestimmten Seitenbereich

<div class="container" ng-controller="testCtrl">  
    <div class="gutter col hidden-xs">&nbsp;</div> 
    <div class="content col" > 

     <div class="py80"> 

      <h1>{{context.test}}</h1> 

     </div> 

    </div> 
    <div class="gutter col hidden-xs">&nbsp;</div> 
</div> 

<!-- ANGULAR CONTROLLER FOR THIS PAGE --> 
<script src="/public/js/angular/test_controller.js"></script> 
Footer

- enthält den Link für den globalen Umfang an die Steuerung

<footer id="footer" ></footer> 
</div></body></html> <!-- close tags--> 

<!-- ANGULAR CONTROLLER FOR GLOBAL CONFIGURATION SCOPE --> 
<script src="/public/js/angular/config_controller.js"></script> 

Hier ist mein Eckige-Controller für die "Konfigurationsbereich"

var app = angular.module('angular', []); 

app.controller('configCtrl', function($scope, $http) { 

    console.log("config controller"); 

    $http.get('/config').then(function(response){ 

     console.log(response.data); 

     $scope.context = response.data; 

    }); 

}); 

Hier ist mein Eckige Controller für die Seite Umfang

var app = angular.module('angular', []); 

app.controller('testCtrl', function($scope, $http) { 

    console.log("test controller"); 

    $http.get('/test').then(function(response){ 

     console.log(response.data); 

     $scope.context = response.data; 

    }); 

}); 

Ich habe einige serverseitige Controller Daten zurück in Winkel Rückkehr, wie erwähnt, sie jede Arbeit, wenn sie unabhängig verwendet, sondern sie zusammen verwendet (wie oben dargestellt) führt den folgenden clientseitige Fehler:

angular.js:13920 Error: [ng:areq] http://errors.angularjs.org/1.5.8/ng/areq?p0=testCtrl&p1=not%20a%20function%2C%20got%20undefined 
at angular.js:38 
at sb (angular.js:1892) 
at Pa (angular.js:1902) 
at angular.js:10330 
at ag (angular.js:9451) 
at p (angular.js:9232) 
at g (angular.js:8620) 
at g (angular.js:8623) 
at g (angular.js:8623) 
at g (angular.js:8623) 

Anregungen ?

Antwort

2

Das Problem ist, dass Sie die App zweimal initialisieren. Tun Sie dies nur einmal:

var app = angular.module('angular', []); 

Und alles wird gut. Am günstigsten ist es, dass die Leitung zu trennen in einer anderen Datei vollständig (wie ‚App-initialize.js‘) und dann können Sie einfach tun:

angular.module('angular').controller(...); 

in all Ihre Dateien.

+0

funktioniert! Danke. Ich dachte, es war etwas Einfaches – yevg

1

Sie rufen diese Zeile zweimal (basierend auf Ihrem Beispiel), die zweimal ein Modul namens 'eckig' erstellen wird.

Anstatt einen Controller für die Konfiguration zu verwenden, können Sie auch eine Factory oder einen Service erstellen und in einen beliebigen Controller einspeisen. (grob :)

var app = angular.module('someApp', []); 
app.controller('testCtrl', function($scope, $http, configFactory) { 

    $scope.getConfig = function() { 
     configFactory.getConfig() 
     .success(function (someConfig) { 
      console.log(someConfig); 
     }); 
    } 

    $scope.getConfig(); 

    console.log("test controller"); 
    $http.get('/test').then(function(response){ 
     console.log(response.data); 
     $scope.context = response.data; 
    }); 

}); 
app.factory('configFactory', ['$http', function($http) { 
    var getConfig = function() { 
     return $http.get('/config'); 
    } 
    return getConfig; 
}]); 

Alternativ können Sie ein Konfigurationsmodul erstellen und übergeben, daß als Abhängigkeit.

var config = angular.module('config', []).constant('config', { 'something': 2 }); 
... 

var app = angular.module('someApp', ['config']); 
... 
+0

ah! danke für die Lösung und Tipp auf Best Practice! – yevg

Verwandte Themen