角度js模型关系

Posted

技术标签:

【中文标题】角度js模型关系【英文标题】:angular js model relationships 【发布时间】:2013-01-09 21:58:08 【问题描述】:

过去几天我一直在尝试 Angular JS,但我不知道如何处理模型之间的关系。

我正在处理的项目有一个用户模型和一个帐户模型。我在我的数据库中设置了每个帐户都有一个名为“ownedBy”的字段,该字段是对拥有该帐户的用户 ID 的外键引用。

在 Angular 中,我在名为 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();

和下面的模板

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

这是有效的。它从我的 REST 服务器中提取 JSON 资源并将其显示在表格中。我需要采取什么下一步才能最终得到一个显示用户及其帐号的表格? (相当于数据库JOIN?)对于一对多关系是否有不同的方法? (即……一个帐户有很多交易)

感谢您的帮助:)

【问题讨论】:

您可以控制服务器返回的内容吗?在将模型与 Angular 绑定之前,您应该根据需要重新构建模型,而最好的位置是在您的服务器 api 中。 @BenFelda 使用 RESTful API,进行客户端连接很常见。 我确实可以控制服务器返回的内容。但我认为最好将用户模型和帐户模型分开(标准化?)。您如何建议我让服务器返回数据? 我会在服务器端构建对象user: account, account...,这样客户端就可以获取数据并将其绑定到我的模型,然后只需调用一次服务器即可获取所有数据。跨度> 我确实在这个帖子中回复了这个:***.com/a/17055281/1558820 【参考方案1】:

如果我需要 UI 中的关系,我会使用 js-data。该库通常非常优雅地处理关系和数据建模。即使您只是在寻找一个不错的 API 接口,我也发现它更易于使用。我更喜欢它而不是 ngResource。

在您的情况下,您将有一个用户模型和帐户模型

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'

【讨论】:

【参考方案2】:

$resource 不包含任何处理不由服务器处理的关系的方法,但使用$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;
    
  ;
);

然后在您的控制器中,您可以像使用任何其他承诺一样使用它:

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

它适用于您的模板!

<div>
    User: "user.firstName user.lastName" with Acct ID "user.acct.id".
</div>

【讨论】:

感谢您的回答,看来它会起作用。我认为 $resource 包装了 $http 并且应该在某些方面更胜一筹。如果有的话,我应该在什么时候使用 $resource? 确实 包装了 $http 和 $resource 对于非常典型的 REST 用例来说非常棒。但是,一旦您冒险超越基础知识,$resource 就会开始妨碍您。例如,您可以使用 $resource 来解决这个问题,但它更加棘手和混乱。最常见的抱怨之一(包括我自己的)是 $resource 没有返回承诺,这很容易。 你可以使用承诺 $http 返回而不是 $q ——也就是说,你使用 $q 有什么原因吗?另外,返回“deferred”与返回“deferred.promise”有区别吗?我问是因为我看到 $q API 文档使用后者。我没有尝试运行你的代码(还)。 @MarkRajcok 返回deferred 而不是deferred.promise 是一个错字。 :-) 我修好了它。只要对then 的内部调用返回 修改后的对象,我们可能会从$http 返回promise,而不是从$q 中返回我们自己的promise。不过,我不是 100% 确定。我都使用了这种方式,因此我不必对其进行测试,因此幕后发生的事情会更清楚。 @AlexMcMillan 在这种情况下,不。但我假设在大多数情况下,服务会希望以某种方式处理错误,而不是在(可能至少)多个控制器中重复处理它。所以我在这里选择了冗长。

以上是关于角度js模型关系的主要内容,如果未能解决你的问题,请参考以下文章

Node.js ORM框架Sequlize之表间关系

Sequelize.js 插入具有一对多关系的模型

Adonis JS v5 关系缺少模型属性

DataBaseSystem:Relational Data Structure

模型与算法之间是啥关系?

数据库学习笔记——关系模式