javascript - tutorial - guida angular 6




Sviluppo di un'app AngularJS con un insieme dinamico di moduli (2)

Questa domanda è anche molto importante per me. La homepage di AngularJS contiene alcuni esempi (potresti chiamarli widgets) quindi ho scelto il loro codice sorgente per provare a vedere come hanno separato i loro widget.

Innanzitutto, non dichiarano mai un attributo "ng-app". Usano

function bootstrap() {
      if (window.prettyPrint && window.$ && $.fn.popover && angular.bootstrap &&
          hasModule('ngLocal.sk') && hasModule('ngLocal.us') && hasModule('homepage') && hasModule('ngResource')) {
            $(function(){
              angular.bootstrap(document, ['homepage', 'ngLocal.us']);
            });
      }
    }

per assicurarsi che tutto sia stato caricato correttamente. Un'idea carina, ma è strano che spingano l'attributo ng-app su di te così tanto da non usarlo nemmeno da soli. Comunque qui è il modulo della homepage che caricano con l'app - http://angularjs.org/js/homepage.js

In c'è una direttiva chiamata appRun

  .directive('appRun', function(fetchCode, $templateCache, $browser) {
    return {
      terminal: true,
      link: function(scope, element, attrs) {
        var modules = [];

        modules.push(function($provide, $locationProvider) {
          $provide.value('$templateCache', {
            get: function(key) {
              var value = $templateCache.get(key);
              if (value) {
                value = value.replace(/\#\//mg, '/');
              }
              return value;
            }
          });
          $provide.value('$anchorScroll', angular.noop);
          $provide.value('$browser', $browser);
          $locationProvider.html5Mode(true);
          $locationProvider.hashPrefix('!');
        });
        if (attrs.module) {
          modules.push(attrs.module);
        }

        element.html(fetchCode(attrs.appRun));
        element.bind('click', function(event) {
          if (event.target.attributes.getNamedItem('ng-click')) {
            event.preventDefault();
          }
        });
        angular.bootstrap(element, modules);
      }
    };
  })

Userò la lista degli impegni come esempio. Per l'html, hanno

<div app-run="todo.html" class="well"></div>

e poi in fondo alla pagina che hanno

<script type="text/ng-template" id="todo.html">
  <h2>Todo</h2>
  <div ng-controller="TodoCtrl">
    <span>{{remaining()}} of {{todos.length}} remaining</span>
    [ <a href="" ng-click="archive()">archive</a> ]
    <ul class="unstyled">
      <li ng-repeat="todo in todos">
        <input type="checkbox" ng-model="todo.done">
        <span class="done-{{todo.done}}">{{todo.text}}</span>
      </li>
    </ul>
    <form ng-submit="addTodo()">
      <input type="text" ng-model="todoText"  size="30"
             placeholder="add new todo here">
      <input class="btn-primary" type="submit" value="add">
    </form>
  </div>
</script>

Loro hanno anche

<style type="text/css" id="todo.css"> //style stuff here </style>
<script id="todo.js"> //controller stuff here </script>

Il codice viene utilizzato, ma gli attributi id su quegli script non sono importanti per l'esecuzione dell'app. Questo è solo per la visualizzazione del codice sorgente a sinistra dell'app.

Fondamentalmente, hanno una direttiva chiamata appRun che usa una funzione fetchCode

  .factory('fetchCode', function(indent) {
    return function get(id, spaces) {
      return indent(angular.element(document.getElementById(id)).html(), spaces);
    }
  })

per prendere il codice. Quindi usano angular.bootstrap () per creare una nuova applicazione. Possono anche caricare i moduli tramite app-run. L'esempio del progetto JavaScript è inizializzato come

<div app-run="project.html" module="project" class="well"></div>

Speriamo che questo aiuti. Non sono ancora sicuro di quale sia la tecnica "migliore", ma sembra che la homepage di AngularJS utilizzi semplicemente un'applicazione angolare completamente separata (ng-app) per ogni esempio / widget. Penso che farò lo stesso, tranne cambiare la funzione fetchCode per ottenere cose con AJAX.

Ho un'applicazione con un layout complesso in cui l'utente può inserire (trascina / rilascia) i widget (scegliendo da un set predefinito di oltre 100 widget) in cui ogni widget è un'implementazione personalizzata che visualizza un insieme di dati (recuperati utilizzando la chiamata REST) in un modo specifico. Ho letto un sacco di post sul blog, domande sullo stackoverflow e documenti ufficiali di AngularJS, ma non riesco a capire come dovrei progettare la mia applicazione per gestire i requisiti. Guardando le app demo, c'è un singolo modulo (ng-app) e quando lo si costruisce nel file .js i moduli dipendenti sono dichiarati come dipendenze, tuttavia ho un grande set di widget e in qualche modo non è consigliabile descriverli tutti Là. Ho bisogno di suggerimenti per le seguenti domande:

  • Come dovrei progettare la mia app e i miei widget - dovrei avere un modulo AngularJS separato o ogni widget dovrebbe essere una direttiva per il modulo principale?
  • Se progetto il mio widget come direttive, c'è un modo per definire la dipendenza all'interno di una direttiva. Vale a dire che la mia direttiva usa ng-calender nella sua implementazione?
  • Se progetto ciascun widget come modulo separato, c'è un modo per aggiungere dinamicamente il modulo widget come dipendenza dal modulo principale?
  • Come dovrei progettare i controller - probabilmente un controller per widget?
  • Come dovrei separare lo stato (scope) se ho più widget dello stesso tipo nella vista?
  • Esistono best practice per la progettazione di widget riutilizzabili con AngularJS?

MODIFICARE

Riferimenti utili:


Questi sono solo consigli generali.

Come dovrei progettare la mia app e i miei widget - dovrei avere un modulo AngularJS separato o ogni widget dovrebbe essere una direttiva per il modulo principale?

Stai parlando di hundres di widget, sembra naturale dividerli in più moduli. Alcuni widget potrebbero avere più in comune di altri widget. Alcuni potrebbero essere molto generali e adattarsi ad altri progetti, altri sono più specifici.

Se progetto il mio widget come direttive, c'è un modo per definire la dipendenza all'interno di una direttiva. Vale a dire che la mia direttiva usa ng-calender nella sua implementazione?

Le dipendenze rispetto ad altri moduli sono fatte a livello di modulo, ma non c'è alcun problema se il modulo A dipende dal modulo B e sia A sia B dipendono dal modulo C Le direttive sono una scelta naturale per la creazione di widget in Angular. Se una direttiva dipende da un'altra direttiva, puoi definirle nello stesso modulo o creare la dipendenza a livello modulare.

Se progetto ciascun widget come modulo separato, c'è un modo per aggiungere dinamicamente il modulo widget come dipendenza dal modulo principale?

Non sono sicuro del perché vorresti farlo e non sono sicuro di come farlo. Direttive e servizi non sono inizializzati prima di essere utilizzati in Angular. Se possiedi un'enorme libreria di direttive (widget) e sai che probabilmente ne userai alcune, ma non tutte, ma non sai quali saranno usate quando l'applicazione verrà inizializzata, puoi davvero "pigro" carica "le tue direttive dopo che il tuo modulo è stato caricato. Ho creato un esempio here

Il vantaggio è che puoi caricare velocemente la tua applicazione anche se hai un sacco di codice, perché non devi caricare gli script prima di averne bisogno. Lo svantaggio è che ci può essere un ritardo considerevole la prima volta che viene caricata una nuova direttiva.

Come dovrei progettare i controller - probabilmente un controller per widget?

Probabilmente un widget avrà bisogno del proprio controller. I controllori dovrebbero essere generalmente piccoli, se diventano grandi puoi considerare se c'è qualche funzionalità che si adatterebbe meglio in un servizio.

Come dovrei separare lo stato (scope) se ho più widget dello stesso tipo nella vista?

I widget che richiedono variabili di ambito dovrebbero avere senza dubbio i propri ambiti isolati ( scope:{ ... } nella configurazione direttiva).

Esistono best practice per la progettazione di widget riutilizzabili con AngularJS?

Isolare l'ambito, mantenere le dipendenze al minimo necessario. Guarda il video di Misko sulle migliori pratiche in Angular

Brian Ford ha anche scritto un articolo sulla scrittura di un'enorme applicazione in Angular





angularjs