角度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模型关系的主要内容,如果未能解决你的问题,请参考以下文章