Come definire due app / moduli angolari in una pagina?


118

Sto cercando di aggiungere due app / moduli angolari a una pagina. Nei violini sottostanti puoi vedere che sempre solo il primo modulo, referenziato nel codice html, funzionerà correttamente, mentre il secondo non viene riconosciuto da angular.

In questo violino possiamo solo eseguire il doSearch2metodo, mentre in questo violino solo il doSearchmetodo funziona correttamente.

Sto cercando il modo per posizionare correttamente due moduli angolari in una pagina.

Risposte:


123

È possibile eseguire il bootstrap automatico di una sola applicazione AngularJS per documento HTML. La prima ngApp trovata nel documento verrà utilizzata per definire l'elemento root per l'auto-bootstrap come un'applicazione. Per eseguire più applicazioni in un documento HTML è necessario eseguirne il bootstrap manualmente utilizzando angular.bootstrap. Le applicazioni AngularJS non possono essere annidate l'una nell'altra. - http://docs.angularjs.org/api/ng.directive:ngApp

Guarda anche


@MarkRajcok Quindi è buona norma avere un solo modulo per documento HTML? L'esempio "Collega un backend" sui set di pagine principali di AngularJS ng-app="project"e dice che "questo ti consente di avere moduli che vengono eseguiti in diverse parti della pagina", ma il documento ngApp afferma che "è possibile utilizzare solo una direttiva per documento HTML".
theblang

9
@mattblang, i moduli sono associati alle applicazioni Angular e non ai documenti HTML. Normalmente è necessaria solo un'app per pagina / documento, ma se si desidera eseguire più applicazioni Angular (ognuna delle quali può utilizzare uno o più moduli) sulla stessa pagina / documento, sarà necessario eseguire manualmente il bootstrap di ciascuna di esse - - non usare ng-app(perché non funzionerà). ng-apppuò essere utilizzato solo una volta per documento HTML. È davvero solo una scorciatoia se hai solo un'app sulla pagina, che è il caso normale.
Mark Rajcok

1
C'è un esempio di questo? Vedo la documentazione dell'api boostrap concisa ma non sono in grado di farlo funzionare. Ho cercato su Google questo per un po 'e non sembra esserci un solo esempio funzionante. Inoltre, come nel mondo funzionerebbe con le rotte? Ovviamente c'è un problema di collisione.
Robert Christian

Inoltre, mi piace molto il modo in cui l'utilizzo di ng-app mostra a un altro sviluppatore esattamente quale parte della pagina è controllata da quale modulo. Non c'è modo di utilizzare il markup sulla pagina per ottenere ciò? O almeno, qualche suggerimento nel markup?
chrismarx il

1
I primi due paragrafi per la direttiva ng-app dicono tutto - docs.angularjs.org/api/ng.directive:ngApp
simo

38

Ho creato una direttiva alternativa che non ha ngApplimitazioni. Si chiama ngModule. Ecco come apparirà il codice quando lo usi:

<!DOCTYPE html>
<html>
    <head>
        <script src="angular.js"></script>
        <script src="angular.ng-modules.js"></script>
        <script>
          var moduleA = angular.module("MyModuleA", []);
          moduleA.controller("MyControllerA", function($scope) {
              $scope.name = "Bob A";
          });

          var moduleB = angular.module("MyModuleB", []);
          moduleB.controller("MyControllerB", function($scope) {
              $scope.name = "Steve B";
          });
        </script>
    </head>
    <body>
        <div ng-modules="MyModuleA, MyModuleB">
            <h1>Module A, B</h1>
            <div ng-controller="MyControllerA">
                {{name}}
            </div>
            <div ng-controller="MyControllerB">
                {{name}}
            </div>
        </div>

        <div ng-module="MyModuleB">
            <h1>Just Module B</h1>
            <div ng-controller="MyControllerB">
                {{name}}
            </div>
        </div>
    </body>
</html>

Puoi ottenere il codice sorgente su:

http://www.simplygoodcode.com/2014/04/angularjs-getting-around-ngapp-limitations-with-ngmodule/

È essenzialmente lo stesso codice utilizzato internamente da AngularJS senza limitazioni.


luisperezphd: ho letto il tuo post sul blog. Esiste un modo per annidare le app (ad esempio un generatore di widget con un widget caricato AJAX) o rilevare se una pagina ha già un'app e iniettare un'altra app come dipendenza della prima? Ho appena pubblicato la mia domanda qui con maggiori dettagli su esattamente ciò che sto cercando di ottenere. Grazie!
Daniel Bonnell,

@ACIDSTEALTH Il fatto che AngularJS stia segnalando che l'elemento già avviato significa che ci deve essere un modo per dirlo, anche se quel codice potrebbe essere interno ad AngularJS. Per scoprirlo, puoi fare riferimento alla versione non ridotta di AngularJS e al punto di interruzione su quell'errore per vedere la condizione if. Da quello che riesco a capire dal tuo link alla domanda StackOverflow, sembra che tu voglia "iniettare" dinamicamente un modulo in fase di esecuzione. Se è così potresti dare un'occhiata a questo articolo: weblogs.asp.net/dwahlin/…
Luis Perez

Ehi @LuisPerez, ho controllato il tuo sito web. L'ho stancato sulla mia macchina. angularJS non sta rilevando "ng-modules" / "ng-module". Ho bisogno di riferimenti inclusi nel mio file?
sujay kodamala

Sì @sujaykodamala, ngModule non è integrato in AngularJS è una direttiva che ho creato. Puoi scaricarlo da GitHub. Puoi trovarlo qui: github.com/luisperezphd/ngModule
Luis Perez

Ciao @Luis Perez! Stavo controllando il tuo post sul blog e sono davvero fantastici. Se hai tempo, potresti controllare il mio post qui per risolvere un problema: stackoverflow.com/questions/46952478/… . Grazie.
user8512043

19

Perché desideri utilizzare più [ng-app]? Poiché Angular viene ripreso utilizzando i moduli, è possibile utilizzare un'app che utilizza più dipendenze.

Javascript:

// setter syntax -> initializing other module for demonstration
angular.module('otherModule', []);

angular.module('app', ['otherModule'])
.controller('AppController', function () {
    // ...do something
});

// getter syntax
angular.module('otherModule')
.controller('OtherController', function () {
    // ...do something
});

HTML:

<div ng-app="app">
    <div ng-controller="AppController">...</div>
    <div ng-controller="OtherController">...</div>
</div>

MODIFICARE

Tieni presente che se vuoi usare il controller all'interno del controller devi usare la sintassi controllerAs, in questo modo:

<div ng-app="app">
    <div ng-controller="AppController as app">
        <div ng-controller="OtherController as other">...</div>
    </div>
</div>

Errore non rilevato: [$ injector: modulerr] errors.angularjs.org/1.3.14/$injector/…… criptMinification% 2Fbower_components% 2Fangular% 2Fangular.min.js% 3A17% 3A381)
Anandaraja_Srinivasan

Hai provato a invertire l'ordine dei 2 moduli? ('OtherModule' prima di 'app') Perché uso molto questa soluzione e funziona perfettamente ...
Monkey Monk

1
Ok ! Ho visto un errore nell'esempio Javascript fornito. Penso che ora sia stato risolto! Per la cronaca, userò la sintassi setter in 2 punti per lo stesso modulo ... che ovviamente non è consentito! :-)
Monkey Monk

il modo in cui ci atteggiamo a farlo
Harry Bosh,

9

Puoi eseguire il bootstrap di più applicazioni angolari, ma:

1) È necessario eseguirne il bootstrap manualmente

2) Non dovresti usare "document" come root, ma il nodo in cui è contenuta l'interfaccia angolare:

var todoRootNode = jQuery('[ng-controller=TodoController]');
angular.bootstrap(todoRootNode, ['TodoApp']);

Questo sarebbe sicuro.


3

Il bootstrap manuale di entrambi i moduli funzionerà. Guarda questo

  <!-- IN HTML -->
  <div id="dvFirst">
    <div ng-controller="FirstController">
      <p>1: {{ desc }}</p>
    </div>
  </div>

  <div id="dvSecond">
    <div ng-controller="SecondController ">
      <p>2: {{ desc }}</p>
    </div>
  </div>



// IN SCRIPT       
var dvFirst = document.getElementById('dvFirst');
var dvSecond = document.getElementById('dvSecond');

angular.element(document).ready(function() {
   angular.bootstrap(dvFirst, ['firstApp']);
   angular.bootstrap(dvSecond, ['secondApp']);
});

Ecco il collegamento al Plunker http://plnkr.co/edit/1SdZ4QpPfuHtdBjTKJIu?p=preview

NOTA: in html, non c'è ng-app. idè stato invece utilizzato.


0

Ho creato un POC per un'applicazione Angular utilizzando più moduli e prese di router per annidare le app secondarie in un'app a pagina singola. Puoi ottenere il codice sorgente su: https://github.com/AhmedBahet/ng-sub-apps

Spero che questo ti aiuti

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.