我是 Angular 新手,但在编码方面有相当多的经验,并且在“正确” View 中获取数据绑定(bind)时遇到一些问题。
我的方法大致是:
- 将所有逻辑保留在 Controller 之外,并将它们封装在服务中(请参阅 this blog )
- 按照 John Papa's style guide 使用
ControllerAs
语法.
我遇到的困惑是,没有显式的 $scope
对象会混淆 MVC 哲学中的模型。有一个passing comment在博客文章中,我看到了这一点,但我没有看到关于此事的任何真正的结论。
Angular 文档指出该模型是数据的“单一事实点”。也许我读得太多了(这只是 V 和 C 之间值的“真相”吗?)但这表明,如果您使用 ControllerAs
语法,则 Controller 属性是模型——以及“单点真理”。
如果这是给定的,并且您希望将所有逻辑抽象到服务中,那么在我看来,您无法摆脱将 Controller 属性保留在两个相当难看的替代方案中的一个与服务值(value)观同步:
- 向 View 公开服务。即
myController.data = service.data
。这可行,但相当粗糙,因为所有服务数据都暴露给 View ,而这些瘦 Controller 的目的不是充当 View 的外观吗?或者换个 Angular 来看,该服务现在已经成为一个事实上的“胖” Controller ,充满了业务逻辑。 - 仅公开您希望 View 访问的服务中的元素,但在每个元素上放置
$watch
表达式。这并不理想,因为- 您向 Controller 添加了大量样板
- 您在代码中显着增加了监视表达式的数量(Angular 在模板 <-> Controller 链接上放置了一个监视,并且您添加了 Controller <-> 服务链接;对于 中的每个变量)
这些真的是 Angular 1.3 中实现此目的的唯一方法吗?或者我错过了一些(更优雅的)东西?
编辑:根据答案和一些额外的调查,我在此 plunkr 中收集了我对此问题的想法。 。它涵盖了 3 种不进行服务绑定(bind)的方法(恕我直言)以及两种可能更接近“正确”方法的方法。
最佳答案
服务返回模型。 Controller 与服务交互以填充 View 模型($scope)。 View 与 View 模型交互以渲染 View 。
为了保持数据同步,您有几个可用的选项。
选项 1:引入一个工厂或服务,其工作是跟踪实例 - 例如缓存服务。任何需要实例来绑定(bind)到 View 的 Controller 都可以从服务中请求它。这很干净 - 不需要显式的监视表达式或非特定的模型绑定(bind)。
这是一个例子。假设您想要跨多个 Controller 绑定(bind)到一个 User 对象。
创建用户服务
app.factory('UserService', function() {
return {
getUserById: function(id) {
...
return user;
}
}
});
创建缓存用户服务
app.factory('CachedUserService', function(UserService) {
var cache = [];
return {
getUserById: function(id) {
if (!cache[id])
cache[id] = UserService.getUserById(id);
return cache[id];
}
}
});
在这里,我们利用单例(所有工厂和服务都是单例),并依靠缓存服务来保存模型引用。后一点对于确保 View 更改与模型更改同步至关重要。
在任何需要它的 Controller 中使用缓存用户服务:
app.controller('ctrl', function($scope, CachedUserService) {
$scope.user = CachedUserService.getUserById(...);
});
选项 2:只需将您想要保持同步的模型存储在 $scope 链的较高位置(即 $rootScope)
app.controller('ctrl', function($scope, $rootScope, UserService) {
$rootScope.user = UserService.getUserById(...);
}
由于原型(prototype)作用域继承,任何子作用域都能够绑定(bind)到作用域链上方的模型。但是请小心,当您在 $scope 上分配或覆盖模型时 - 您可能会无意中破坏模型绑定(bind)。要保留引用,请改用 angular.copy
。
关于angularjs - 将服务数据绑定(bind)到 Angular View 的最佳实践是什么(1.3),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31050534/