2012-10-15 13 views
5

Sto cercando di creare alcune direttive che interagiscano con il controller/scope genitore in qualche modo. Faccio CRUD in 2 modi: A) Percorso in base al quale, se stai per modificare un articolo, utilizzo $ posizione per cambiare l'url in un dato URL B) Stessa Pagina in cui, se fai clic su modifica su un elemento che imposta $ scope.template da $ scope.tpl, quindi nel partial ho un ng-hide/show che nasconde e mostra la vista tabella/vista dettagli.AngularJS - Direttiva CRUD/schemi di servizio/controller

Quello che voglio ottenere è forse avere meno codice nelle mie direttive e magari usare un approccio o un suggerimento più basato sui servizi?

direttive

'use strict'; 

/* Directives */ 
var directives = angular.module("app.directives", ["ui"]); 


function CrudCtrl($scope, $attrs, $location, $parse) { 
    function getScope(scopeName) { 
     scopeName = typeof scopeName || "$parent"; 
     var ngModel = $parse(scopeName, $scope); 
     return ngModel($scope) 
    } 

    function refreshObjects(scopeName) { 
     $scope.svc.query($scope.params, function(objects) { 
      var parentScope = getScope(scopeName) 
      parentScope.objects = objects 
     }); 
    } 

    if (!$scope.refreshObjects) { 
     $scope.refreshObjects = function() { 
      refreshObjects($attrs.modelname) 
     } 
    } 

    if (!$scope.crudAdd) { 
     $scope.crudAdd = function() { 
      if ($attrs.url) { 
       $location.path($attrs.url); 
       return; 
      } else { 
       var parentScope = getScope($attrs.scope); 
       parentScope.object = new $scope.svc(); 
       parentScope.template = parentScope.tpl; 
      } 
     } 
    } 

    if (!$scope.crudDelete) { 
     $scope.crudDelete = function() { 
      /* Fire off a delete and as a callback we update objects */ 
      $scope.svc.delete({accountId: $scope.account.uuid, id: $scope.object.id}, function() { 
       refreshObjects($attrs.scopeName) 
      }); 
     }; 
    } 

    if (!$scope.crudEdit) { 
     $scope.crudEdit = function() { 
      if ($attrs.url) { 
       $location.path($attrs.url); 
       return; 
      } else { 
       var parentScope = getScope($attrs.scopeName); 
       parentScope.object = $scope.object; 
       parentScope.template = parentScope.tpl; 
      } 
     }; 
    } 

    if (!$scope.crudSave) { 
     $scope.crudSave = function() { 
      var params = {} 
      params.accountId = $scope.params.accountId 
      if ($scope.object.id) { params.id = $scope.object.id } 

      $scope.object.$save(params, function() { 
       if ($attrs.url) { 
        $scope.back(); 
       } else { 
        refreshObjects($attrs.scopeName); 

        var parentScope = getScope($attrs.scopeName); 
        parentScope.template = undefined; 
       } 
      }); 
     }; 
    } 

    if (!$scope.crudCancel) { 
     $scope.crudCancel = function() { 
      if (parentScope.template) { 
       var parentScope = getScope($attrs.scopeName); 
       parentScope.template = undefined; 
      } else { 
       $scope.back(); 
      } 
     }; 
    }; 
}; 


directives.directive("refresh", function() { 
    return { 
     restrict: "E", 
     replace: true, 
     controller: CrudCtrl, 
     scope: true, 
     link: function(scope, element, attrs) { 
      scope.display_text = attrs.text; 
     }, 
     template: '<button class="btn btn-mini btn-primary" ng-click="refreshObjects()"><i class="icon-refresh"></i> Refresh</button>', 
    }; 
}); 


/* Create something new */ 
directives.directive("create", function() { 
    return { 
     restrict: "E", 
     replace: true, 
     controller: CrudCtrl, 
     scope: true, 
     link: function(scope, element, attrs) { 
      scope.display_text = attrs.text; 
     }, 
     template: '<button class="btn btn-mini btn-success" ng-click="crudAdd()"><i class="icon-plus"></i> {{display_text || "Add"}}</button>', 
    }; 
}); 


/* Delete button and update objects */ 
directives.directive("delete", function() { 
    return { 
     restrict: "E", 
     replace: true, 
     controller: CrudCtrl, 
     scope: true, 
     link: function(scope, element, attrs) { 
      scope.display_text = attrs.text; 
     }, 
     template: '<button class="btn btn-mini btn-danger" ng-click="crudDelete()"><i class="icon-remove icon-white"></i> {{display_text}}</button>', 
    } 
}); 

/* Helper to create a edit button */ 
directives.directive("edit", function() { 
    return { 
     restrict: "E", 
     replace: true, 
     controller: CrudCtrl, 
     scope: true, 
     link: function(scope, element, attrs) { 
      scope.display_text = attrs.text; 
     }, 
     template: '<button class="btn btn-mini btn-info" ng-click="crudEdit()"><i class="icon-edit"></i> {{display_text || "Edit"}}</a>', 
    } 
}); 

/* Save the object and return to the previous page */ 
directives.directive("save", function() { 
    return { 
     restrict: "E", 
     replace: true, 
     controller: CrudCtrl, 
     scope: true, 
     link: function(scope, element, attrs) { 
      scope.display_text = attrs.text; 
     }, 
     template: '<button class="btn btn-success" ng-click="crudSave()"><i class="icon-ok"> {{display_text || "Save"}}</i></a>', 
    }; 
}); 

/* Cancel the current action */ 
directives.directive("cancel", function() { 
    return { 
     restrict: "E", 
     replace: true, 
     controller: CrudCtrl, 
     scope: true, 
     link: function(scope, element, attrs) { 
      scope.display_text = attrs.text; 
     }, 
     template: '<button class="btn" ng-click="crudCancel()"><i class="icon-remove"></i> {{display_text || "Cancel"}}</button>' 
    } 
}); 

Un controllore esempio

function BookingCtrl($scope, Booking) { 
     $scope.svc = Booking; 
     $scope.objects = $scope.svc.query($scope.params); 
    } 

Poi in una parziale per una panoramica ho:

<div ng-hide="template"> 
<refresh></refresh> 
<create url="/{{params.accountId}}/entity/add"></create> 

<table class="table table-condensed table-hover"> 
    <thead> 
     <tr> 
      <th></th> 
      <th>Name</th> 
      <th>Description</th> 
     </tr> 
    </thead> 
    <tbody> 
     <tr ng-repeat="object in objects"> 
      <td> 
       <delete></delete> 
       <edit url="/{{params.accountId}}/category/{{object.resource_id}}"></edit> 
      </td> 
      <td>{{object.resource_name}}</td> 
      <td>{{object.description}}</td> 
     </tr> 
     </tr> 
     </tr> 
    </tbody> 
</table> 
</div> 

<ng-show="template" ng-include src="template"></ng-show> 

dettaglio parziale:

<div class="span4"> 
    <h3>Category: {{category.resource_name}}</h3> 
    <form name="detail_form" class="form-horizontal"> 
     <div class="control-group"> 
      <label class="control-label"><strong>Name</strong></label> 
      <div class="controls"> 
       <input required ng-model="object.resource_name" placeholder="Name" type="text" class="input-small"> 
      </div> 
     </div> 
     <div class="control-group"> 
      <label class="control-label"><strong>Description</strong></label> 
      <div class="controls"> 
       <textarea ng-model="object.description" placeholder="Description" type="textarea" rows=5></textarea> 
      </div> 
     </div> 
     <div class="control-group"> 
      <save scope-name="$parent.$parent"></save> 
      <cancel scope-name="$parent.$parent"></cancel> 
     </div> 
    </form> 
<pre>form = {{object | json}}</pre> 
</div> 

Questo sembra eccessivo per usare $ parent. $ Parent se c'è un modo migliore per risolvere questo per favore aiutatemi!

+0

Il modo angolare è stato progettato in modo che tutti gli ambiti figlio abbiano accesso diretto agli ambiti padre. Se vuoi essere in grado di accedere alle stesse funzionalità su qualsiasi pagina, perché non avere il tuo controller di crude sul wrapper per la sezione di contenuti che devi manipolare? –

risposta

2

vorrei affrontare questo tipo di caratteristica facendo seguenti:

  • messo $resource in servizio.
  • utilizzare ng-view per associare URL e partial. Utilizzare gli ancoraggi per il collegamento ad altri parziali.
  • definire i controller per ciascun parziali in base al ruolo. (accesso $resource via servizio)

http://angularjs.org/#wire-up-a-backend può essere l'esempio.

+0

Già fatto nel controller. ma non voglio scrivere crudAdd e così via ogni volta che scrivo un pulsante? –

+0

Ho già provato questo, ma quello che sto cercando di evitare è per le azioni generali di CRUD. Non voglio scrivere lo stesso codice in ogni controller? Da qui l'approccio a .svc e .object (s). –

Problemi correlati