web-dev-qa-db-fra.com

relations modèle js angulaire

Je teste Angular JS depuis quelques jours et je ne sais pas trop comment travailler avec les relations entre les modèles.

Le projet sur lequel je travaille a un modèle Utilisateurs et un modèle Comptes. Je l'ai configuré dans ma base de données pour que chaque compte ait un champ appelé "ownBy", qui est une référence de clé étrangère à l'identifiant de l'utilisateur qui possède ce compte.

Dans Angular, les éléments suivants sont configurés dans un fichier appelé main.js.

var myApp = angular.module('myApp', ['ngResource']);

var Users = myApp.factory('Users', function($resource) {
    var User = $resource('http://api.mydomain.ca/users/:id',
        {id:'@id'},
    {});
    return User;
});

var Accounts = myApp.factory('Accounts', function($resource) {
    var Accounts = $resource('http://api.mydomain.ca/accounts/:id',
        {id:'@id'},
    {});
    return Accounts;
});


function UsersCtrl($scope, Users) {
    $scope.users = Users.query();
}

function AccountsCtrl($scope, Accounts) {
    $scope.accounts = Accounts.query();
}

et le modèle suivant

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
  <title>Angular Test</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css?v=2.2.1">
</head>
<body>
<div ng-app="myApp">
    <div ng-controller="UsersCtrl">
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>First Name</th>
                    <th>Last Name</th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="user in users">
                    <td>{{user.id}}</td>
                    <td>{{user.firstName}}</td>
                    <td>{{user.lastName}}</td>
                </tr>
            </tbody>
        </table>
    </div>
    <div ng-controller="AccountsCtrl">
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Owned By</th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="account in accounts">
                    <td>{{account.id}}</td>
                    <td>{{account.ownedBy}}</td>
                </tr>
            </tbody>
        </table>
    </div>
</div>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular-resource.min.js"></script>
<script src="/bootstrap/js/bootstrap.min.js?v=2.2.1"></script>
<script src="js/main.js"></script>
</body>
</html>

et ça marche. Il extrait une ressource JSON de mon serveur REST et l'affiche dans un tableau. Quelle est la prochaine étape que je dois entreprendre pour me retrouver avec un tableau présentant les utilisateurs et leurs numéros de compte? (L'équivalent d'une base de données JOIN?) Existe-t-il une façon différente de le faire pour une relation un à plusieurs? (ie ... un compte a beaucoup de transactions)

Merci pour l'aide :)

28
Devin Crossman

$resource ne contient aucun moyen de traiter des relations qui ne sont pas gérées par le serveur, mais c'est tout simplement avec $http:

module.factory( 'UserService', function ( $http, $q ) {
  return {
    get: function getUser( id ) {
      // We create our own promise to return
      var deferred = $q.defer();

      $http.get('/users/'+id).then( function ( user ) {
        $http.get('/accounts/'+user.id).then( function ( acct ) {

          // Add the account info however you want
          user.account = acct;

          // resolve the promise
          deferred.resolve( user );

        }, function getAcctError() { deferred.reject(); } );
      }, function getUserError() { deferred.reject(); } );

      return deferred.promise;
    }
  };
});

Et puis dans votre contrôleur, vous pouvez simplement l'utiliser comme n'importe quelle autre promesse:

UserService.get( $scope.userId ).then( function ( user ) {
  $scope.user = user;
});

Et c'est disponible pour votre modèle!

<div>
    User: "{{user.firstName}} {{user.lastName}}" with Acct ID "{{user.acct.id}}".
</div>
25
Josh David Miller

J'utilise js-data si j'ai besoin de relations dans l'interface utilisateur. La bibliothèque gère les relations et la modélisation des données de manière assez élégante en général. Je l’ai trouvé plus facile à utiliser même si vous recherchez simplement une interface API Nice. Je le préfère à ngResource.

Dans votre cas, vous auriez un modèle pour Utilisateur et un modèle pour Compte.

src/app/data/account.model.coffee

angular.module 'app.data' #this can be your module name
  .factory 'Account', (DS) ->
    DS.defineResource
      name: 'account'
      endpoint: 'accounts'
      relations:
        belongsTo:
          user:
            localKey: 'userId'
            localField: 'user'

src/app/data/user.model.coffee

angular.module 'app.data'
  .factory 'User', (DS) ->

    DS.defineResource
      name: 'user'
      endpoint: 'users'
      relations:
        belongsTo:
          account: #make sure this matches the 'name' property of the other model
            foreignKey: 'userId'
            localField: 'account'
0
Tyrone Wilson