2012-10-15 6 views
5

Je souhaite créer des directives qui interagissent avec le contrôleur/scope parent à certains égards. Je fais CRUD de 2 façons: A) Route basée où si vous êtes sur le point d'éditer un article j'utilise $ location pour changer l'url en une URL donnée B) Sur la même page où si vous cliquez sur modifier sur un élément qu'il définit $ scope.template from $ scope.tpl, puis dans le partiel j'ai un ng-hide/show qui cache et montre la vue table/detail. Ce que je veux accomplir est peut-être d'avoir moins de code dans mes directives et peut-être utiliser une approche plus basée sur le service ou des conseils?AngularJS - Modèles de directive/service/contrôleur CRUD

Directives

'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 exemple contrôleur

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

Puis dans une partielle pour une vue d'ensemble, j'ai:

<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> 

Le détail partiel:

<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> 

Cela semble excessif d'utiliser $ parent. $ Parent s'il y a une meilleure façon de résoudre cela s'il vous plaît aidez-moi!

+0

La conception angulaire a été conçue pour que tous les enfants aient un accès direct aux portées principales. Si vous voulez être en mesure d'accéder à la même fonctionnalité sur n'importe quelle page, alors pourquoi ne pas avoir votre contrôleur de crud sur le wrapper pour la section de contenu que vous devez manipuler? –

Répondre

2

J'aborderions ce genre de fonctionnalité faire followings:

  • mis $resource en service.
  • utiliser ng-view pour lier les urls et les partiels. Utilisez les ancres à lien vers d'autres partiels.
  • définir des contrôleurs pour chaque partiels en fonction de leur rôle. (accès $resource via le service)

http://angularjs.org/#wire-up-a-backend peut-être l'exemple.

+0

Cela est déjà fait dans le contrôleur. mais je ne veux pas avoir à écrire crudAdd et ainsi de suite pour chaque fois que j'écris un bouton? –

+0

J'ai déjà essayé cela, mais ce que je suis à éviter est pour les actions générales de CRUD Je ne veux pas avoir à écrire le même code dans chaque contrôleur? D'où l'approche de .svc et .object (s). –

Questions connexes