functions ejemplo cloak angularjs controller crud

ejemplo - ¿Es una buena práctica combinar los controladores CREATE y EDIT en AngularJS?



ng-init (3)

Hay muchos códigos duplicados entre los controladores CREATE y EDIT. Estos controladores podrían combinarse en uno para minimizar el código repetitivo.

El problema : necesito distinguir qué método usar en el envío de formularios, por ejemplo, create () o edit ().

La solución : podría agregar $scope.mode por ejemplo y establecer $scope.mode=''edit'' si el usuario $scope.mode=''edit'' clic en el botón ''EDITAR'' o configurara $scope.mode=''add'' si el usuario $scope.mode=''add'' clic en el botón ''AÑADIR''.

Podría usar los servicios para minimizar el código repetitivo, pero todavía habrá un código duplicado. Por ejemplo, en ambos controladores tengo el método cancel () que borra el formulario y lo oculta. Podría almacenar clearForm () y hideForm () en el servicio, pero este código se duplicará en ambos controladores:

$scope.cancel = function() { Service.clearForm(); Service.hideForm(); };

Preguntas:

  • ¿Es una buena práctica combinar los controladores CREATE y EDIT en AngularJS?
  • ¿Existen buenas prácticas para minimizar el código repetitivo?

¿Es una buena práctica combinar los controladores CREATE y EDIT en AngularJS?

En mi experiencia, sí, es una buena idea para el 99.9% del tiempo. Por lo general, inyecto una variable formType en mi controlador a través de la función de resolución $ routeProvider. Entonces tendría algo como lo siguiente:

$routeProvider .when(''/item/create'', { templateUrl: ''/app/item/itemForm.html'', controller: ''itemFormController'', resolve: { item: [''$route'', ''itemRepository'', function ($route, itemRepository) { return itemRepository.getNew(); }], formType: function () { return Enums.FormType.CREATE; } }, }) .when(''/item/edit/:itemId'', { templateUrl: ''/app/item/itemForm.html'', controller: ''itemFormController'', resolve: { item: [''$route'', ''itemRepository'', function ($route, itemRepository) { return itemRepository.get($route.current.params.itemId); }], formType: function () { return Enums.FormType.EDIT; }, }, });

De esa manera usted obtiene su entidad y el tipo de acción de formulario inyectada en el controlador. También comparto las mismas plantillas, por lo tanto, al guardar un formulario puedo confiar en mi repositorio / servicio para determinar a qué punto final REST llamar, o puedo hacer una comprobación simple dentro del controlador, dependiendo de qué formType fue inyectado.

¿Existen buenas prácticas para minimizar el código repetitivo?

Algunas de las cosas que estoy usando para mantener las cosas en seco:

Si mantiene una convención común en la API de su servidor, puede recorrer un largo camino con una fábrica / repositorio / clase base (como quiera que lo llame) para el acceso a los datos. Por ejemplo:

GET -> /{resource}?listQueryString // Return resource list GET -> /{resource}/{id} // Return single resource GET -> /{resource}/{id}/{resource}view // Return display representation of resource PUT -> /{resource}/{id} // Update existing resource POST -> /{resource}/ // Create new resource etc.

Luego usamos una fábrica de AngularJs que devuelve una clase de repositorio base, llamémosla abstractRepository . Luego, para cada recurso, creo un repositorio concreto para ese recurso específico que se hereda prototípicamente de abstractRepository, por lo que heredo todas las características compartidas / base de abstractRepository y defino cualquier característica específica de recursos en el repositorio concreto. De esta manera, la gran mayoría de los códigos de acceso a datos se pueden definir en abstractRepository. Aquí hay un ejemplo usando Restangular:

abstracto repositorio

app.factory(''abstractRepository'', [function () { function abstractRepository(restangular, route) { this.restangular = restangular; this.route = route; } abstractRepository.prototype = { getList: function (params) { return this.restangular.all(this.route).getList(params); }, get: function (id) { return this.restangular.one(this.route, id).get(); }, getView: function (id) { return this.restangular.one(this.route, id).one(this.route + ''view'').get(); }, update: function (updatedResource) { return updatedResource.put(); }, create: function (newResource) { return this.restangular.all(this.route).post(newResource); } // etc. }; abstractRepository.extend = function (repository) { repository.prototype = Object.create(abstractRepository.prototype); repository.prototype.constructor = repository; }; return abstractRepository; }]);

Repositorio concreto, usemos al cliente como ejemplo:

app.factory(''customerRepository'', [''Restangular'', ''abstractRepository'', function (restangular, abstractRepository) { function customerRepository() { abstractRepository.call(this, restangular, ''customers''); } abstractRepository.extend(customerRepository); return new customerRepository(); }]);

Lo que encontrará si usa este patrón de repositorio base es que la mayoría de sus controladores CRUD también compartirán una gran cantidad de código común, por lo que normalmente creo un controlador CRUD base del que mis controladores heredan. A algunas personas no les gusta la idea de un controlador base, pero en nuestro caso también ha servido.


La respuesta a su primera pregunta probablemente depende de las circunstancias específicas.

Si los dos controladores comparten una cantidad sustancial de operaciones, y el comportamiento de una o dos funciones debe modificarse, ¡por qué no! Quizás no sea la solución más elegante pero hey, lo que sea que funcione.

Si el comportamiento de muchas o todas las operaciones del controlador dependerá de ''$ scope.mode'' ... diría que tenga cuidado. Eso parece un camino peligroso.

Los servicios angulares siempre me han servido bien cuando se trata de minimizar la replicación de código entre controladores. Si existe una "buena práctica para minimizar el código repetitivo", diría que se trataría de servicios. Son globales para su aplicación y se pueden inyectar en varios controladores sin problema.

¡Espero que eso ayude!


Sí. Utilice 1 controlador.

Esta es la razón por la cual usa 1 controlador

El trabajo del controlador es soportar la vista. La vista de creación y la vista de edición son exactamente iguales: solo una tiene datos rellenados previamente (edición) y otra no (creación). Además, el "propósito" de esta Vista es hacer que el usuario cambie o ingrese nuevos valores en el formulario. Tu única diferencia debería ser algo como reset (). Pero incluso allí puede comenzar con un objeto modelo vacío, por ejemplo, $scope.entity = {} en el caso de CREATE y comenzará con $scope.entity = $http.get() .

Problema de repetición con 2 controladores

Con 2 controladores y servicios diferentes, incurrirá en al menos la siguiente duplicación:

$scope.cancel = function() { Service.cancel(); }; $scope.validate = function() { ValidtionSvc.validate(); } . . .//other stuff similar

Pero el problema es por qué incluso esta duplicación, como usted dijo.

(UDADO aquí en adelante ya que arriba fue la respuesta a la primera pregunta)

¿Cómo utilizar 1 controlador con repetición?

¿Existen buenas prácticas para minimizar el código repetitivo?

Pregunta redefinida: ¿Existe una buena práctica de eliminar el código repetitivo en los formularios CREAR y EDITAR?

Según mi conocimiento, no existe una "mejor práctica" formal para evitar el código repetitivo en esta situación específica. Sin embargo, estoy aconsejando en contra de modo = editar / crear. La razón de ser de los controladores en esta situación es que casi no hay diferencia, ya que su trabajo es simplemente recuperar / actualizar el modelo a medida que el usuario interactúa.

Aquí está la diferencia que encontrará en esta situación y cómo puede evitar si / then / else con mode = create / edit:

1) Rellenar el formulario con los valores existentes frente al formulario vacío para Crear.

Para obtener una entidad existente necesitas algunos datos clave / de consulta. Si estos datos clave están presentes, usted podría hacer

var masterEntity = {}; if(keyData) { masterEntity = MyEntityResourceFactory.getEntity(keyData); } $scope.entity = masterEntity;//for Create this would be {}

2) la forma reset () debe ser simple

$scope.reset = function() { $scope.entity = masterEntity; }

3) Actualizar / Crear

$http.post()//should not be different in today''s world since we are treating PUT as POST

4) Validación: esta es una reutilización perfecta, no debería haber diferencias.

5) Valores iniciales / predeterminados

Puede usar masterEntity = Predeterminados en lugar de {}.