我有一个'帐户'服务,充当多个控制器和视图中使用的集中数据存储。除了getter和setter方法之外,该服务还将保存与两类用户相关的所有数据,即登录用户和匿名用户。
这项服务背后的理念是它应该被用作一个集中的数据结构,它将使所有相关的视图和控制器保持同步。例如:如果用户登录,他们将知道他的电子邮件,并且所有“简报订阅”字段都可以预先填写。
我使用的当前设置如下。请注意,服务器上的每个Async调用都将返回一个promise。
// The Service
angular.module('A').provider('AccountService', [function() {
this.$get = function ($resource) {
var Account = {
getLoggedInAccountAsync : function () {
var Account = $resource(WebApi.Config.apiUrl + 'Account/Get');
return Account.get();
},
getUserData : function () {
return Account.userData;
},
setUserData : function (accountData) {
var merge = angular.extend((Account.currentAccountData || {}), accountData);
Account.currentAccountData = merge;
}
};
return Account;
}
});
// Our main app controller. Get's fired on every page load.
angular.module('A').controller('MainController', ['AccountService', function (AccountService) {
var loggedInAccount = AccountService.getLoggedInAccountAsync();
loggedInAccount.$then(loggedInAccountPromiseResolved);
function loggedInAccountPromiseResolved (response) {
if (response.data.isLoggedIn) {
AccountService.setAccountData(response.data);
}
};
return $scope.MainController= this;
}])
// Our specific controller. For example a newsletter subscription.
angular.module('A').controller('SpecificController', ['AccountService', function (AccountService) {
this.getUserData = AccountService.getUserData;
return $scope.Controller = this;
}])
// Newsletter subscription view
<input id="email" type="email" name="email" ng-model="SpecificController.getUserData().UserName"/>
使用上面的代码确保每当我们使用服务通过Controller.getUserData()。属性将我们的数据绑定到我们的视图时,它将在整个应用程序中保持同步。
如果未定义.UserName值,或者如果没有用户,则上面的代码也将抛出。或者根本没有帐户数据。解决此问题的一种方法是使用空值在我们的服务中“转储”我们的“模板”对象,这将确保键/值存在。另一种方法是使用观察者,让我们的控制器“写”到我们的服务,以防用户填写字段。
第一个选项为我提供了更多的灵活性,因为我可以集中服务中的所有数据绑定,但它感觉很脏,因为你永远不知道服务器数据会发生什么,例如它可能以不同的格式出现。
有没有人有其他解决方案?我宁愿不让我的控制器将数据写入服务。
感谢您的时间!
答案 0 :(得分:2)
这里有很多问题,我会尽我所能回答。
不,你在做什么不是“最佳做法”。
首先,应该将模型直接注入到视图中,并且在“$ scope”的帮助下,维护值是Controller的责任。你的“ng-model =”Controller.getUserData()。UserName“很糟糕。在我下面注意到的博客文章的最后有一个很好的例子。
其次,当你从服务中获取数据时,大部分时间,答案都是异步的,所以你最好看看Promise API。 AngularJS的官方文档并不总是很棒,有时可以在谷歌小组或博客文章中找到答案。
对于您的问题,这是一篇很好的文章:http://markdalgleish.com/2013/06/using-promises-in-angularjs-views/
答案 1 :(得分:2)
$q
。我更喜欢使用承诺,因为它更清晰。我会以更好的方式重写你的片段:
// Service
angular.module('A').provider('AccountService', [function() {
this.$get = function ($resource, $q) {
var Account = {
getUserData : function () {
var d = $q.defer();
d.resolve(Account.userData);
return d.promise;
}
};
return Account;
}
});
// Controller
angular.module('A').controller('Controller', ['AccountService', function (AccountService) {
var init = function() {
getUserData();
};
var getUserData = function() {
AccountService.getUserData().then(function(data) { $scope.username = data; });
};
init();
//return $scope.Controller = this; // you don't need to do this
}])
HTML:
<input id="email" type="email" name="email" ng-model="username"/>