javascript - nuevo - Desarrollar una aplicación AngularJS con un conjunto dinámico de módulos
que es un componente en angular (2)
Esta pregunta también es muy importante para mí. La página de inicio de AngularJS tiene algunos ejemplos (puedes llamarlos widgets), así que revisé su código fuente para ver cómo separaban sus widgets.
En primer lugar, nunca declaran un atributo "ng-app". Ellos usan
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'']);
});
}
}
para asegurarse de que todo esté cargado correctamente. Una idea genial, pero es extraño que presionen tanto el atributo ng-app que ni siquiera lo usen ellos mismos. De todos modos aquí está el módulo de página de inicio que cargan con la aplicación - http://angularjs.org/js/homepage.js
En esta hay una directiva llamada 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);
}
};
})
Usaré la lista de tareas pendientes como un ejemplo. Para el html, tienen
<div app-run="todo.html" class="well"></div>
y luego en la parte inferior de la página tienen
<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>
También tienen
<style type="text/css" id="todo.css"> //style stuff here </style>
<script id="todo.js"> //controller stuff here </script>
El código se usa, pero los atributos de id en esos scripts no son importantes para ejecutar la aplicación. Eso es solo para la visualización del código fuente a la izquierda de la aplicación.
Básicamente, tienen una directiva llamada appRun que usa una función fetchCode
.factory(''fetchCode'', function(indent) {
return function get(id, spaces) {
return indent(angular.element(document.getElementById(id)).html(), spaces);
}
})
para buscar el código Luego usan angular.bootstrap () para crear una nueva aplicación. También pueden cargar módulos a través de la aplicación. El ejemplo del Proyecto JavaScript se inicializa como
<div app-run="project.html" module="project" class="well"></div>
Espero que esto ayude. Todavía no estoy seguro de cuál es la "mejor" técnica, pero parece que la página de inicio de AngularJS simplemente utiliza una aplicación angular totalmente separada (ng-app) para cada ejemplo / widget. Creo que voy a hacer lo mismo, excepto cambiar la función fetchCode para obtener cosas con AJAX.
Tengo una aplicación con un diseño complejo en el que el usuario puede poner (arrastrar / soltar) widgets (eligiendo de un conjunto predefinido de más de 100 widgets) donde cada widget es una implementación personalizada que muestra un conjunto de datos (recuperado mediante una llamada REST) de una manera específica. He leído toneladas de publicaciones en blogs, preguntas sobre stackflow y los documentos oficiales de AngularJS, pero no puedo entender cómo debo diseñar mi aplicación para manejar los requisitos. En cuanto a las aplicaciones de demostración, hay un único módulo (ng-app) y al construirlo en el archivo .js los módulos dependientes se declaran como sus dependencias, sin embargo, tengo un gran conjunto de widgets y de alguna manera no es aconsejable describirlos todos ahí. Necesito sugerencias para las siguientes preguntas:
- ¿Cómo debería diseñar mi aplicación y widgets? ¿Debería tener un módulo AngularJS separado o cada widget debería ser una directiva para el módulo principal?
- Si diseño mi widget como directivas, ¿hay alguna forma de definir la dependencia dentro de una directiva? Es decir, ¿mi directiva usa ng-calendar en su implementación?
- Si diseño cada widget como un módulo separado, ¿hay alguna forma de agregar dinámicamente el módulo de widgets como una dependencia del módulo principal?
- ¿Cómo debería diseñar los controladores? ¿Probablemente un controlador por widget?
- ¿Cómo debo separar el estado (alcance) si tengo múltiples widgets del mismo tipo en la vista?
- ¿Hay mejores prácticas para diseñar widgets reutilizables con AngularJS?
EDITAR
Referencias útiles:
- ocLazyLoad - gran lib carga lenta para AngularJS
- Proyecto semilla: módulos + carga diferida en el cambio de ruta (ES6, systemjs, ocLazyLoad)
- Carga lenta en AngularJS
- Cargar dinámicamente controladores y vistas con AngularJS y RequireJS
- Cargando componentes AngularJS con RequireJS después de la aplicación Bootstrap
- Proyecto de demostración sobre la carga lenta de recursos AngularJS en GitHub
- Proyecto Load On Demand
- Inyectar el módulo dinámicamente solo si es necesario
- Otra carga floja en artículo angular
- Organización de código en grandes aplicaciones AngularJS y JavaScript
Estos son solo consejos generales.
¿Cómo debería diseñar mi aplicación y widgets? ¿Debería tener un módulo AngularJS separado o cada widget debería ser una directiva para el módulo principal?
Estás hablando de cientos de widgets, parece natural dividirlos en varios módulos. Algunos widgets pueden tener más en común que otros widgets. Algunos pueden ser muy generales y encajar en otros proyectos, otros son más específicos.
Si diseño mi widget como directivas, ¿hay alguna forma de definir la dependencia dentro de una directiva? Es decir, ¿mi directiva usa ng-calendar en su implementación?
Las dependencias con otros módulos se hacen a nivel de módulo, pero no hay problema si el módulo A
depende del módulo B
y tanto A
como B
dependen del módulo C
Las directivas son una elección natural para crear widgets en Angular. Si una directiva depende de otra directiva, o las define en el mismo módulo o crea la dependencia en un nivel modular.
Si diseño cada widget como un módulo separado, ¿hay alguna forma de agregar dinámicamente el módulo de widgets como una dependencia del módulo principal?
No estoy seguro de por qué querrías hacer esto, y no estoy seguro de cómo hacerlo. Las directivas y los servicios no se inicializan antes de que se usen en Angular. Si tiene una gran biblioteca de directivas (widgets) y sabe que probablemente utilizará algunas de ellas, pero no todas, pero no sabe cuáles se utilizarán cuando la aplicación se inicialice, en realidad puede ser "flojo". cargue "sus instrucciones después de que su módulo se haya cargado. He creado un ejemplo here
El beneficio es que puede hacer que su aplicación cargue rápidamente incluso si tiene muchos códigos, porque no tiene que cargar los scripts antes de que los necesite. La desventaja es que puede haber un retraso considerable la primera vez que se carga una nueva directiva.
¿Cómo debería diseñar los controladores? ¿Probablemente un controlador por widget?
Un widget probablemente necesitará su propio controlador. Los controladores generalmente deben ser pequeños; si crecen, puede considerar si hay alguna funcionalidad que encaje mejor en un servicio.
¿Cómo debo separar el estado (alcance) si tengo múltiples widgets del mismo tipo en la vista?
Los widgets que necesitan variables de ámbito deberían sin duda tener sus propios ámbitos aislados ( scope:{ ... }
en la configuración de directivas).
¿Hay mejores prácticas para diseñar widgets reutilizables con AngularJS?
Aísle el alcance, mantenga las dependencias a un mínimo necesario. Vea el video de Misko sobre las mejores prácticas en Angular
Brian Ford también ha escrito un artículo sobre cómo escribir una gran aplicación en Angular