Angularjs 什么';s将服务数据绑定到角度视图的最佳实践(1.3)
我是Angular的新手,但在编码方面有相当多的经验,并且在视图中获取数据绑定“正确”时遇到一些困难 我的方法大致如下:Angularjs 什么';s将服务数据绑定到角度视图的最佳实践(1.3),angularjs,Angularjs,我是Angular的新手,但在编码方面有相当多的经验,并且在视图中获取数据绑定“正确”时遇到一些困难 我的方法大致如下: 将所有逻辑排除在控制器之外,并将其封装在服务中(请参阅) 根据使用ControllerAs语法 我感到困惑的是,没有明确的$scope对象会混淆MVC理念中的模型。这篇博文中对此有一个解释,但我没有看到任何关于这件事的真正结论 角度文档声明该模型是数据的“单真实点”。也许我读了很多(这只是V和C之间值的“真值”吗?),但这表明,如果使用ControllerAs语法,控制器
- 将所有逻辑排除在控制器之外,并将其封装在服务中(请参阅)
- 根据使用
语法ControllerAs
$scope
对象会混淆MVC理念中的模型。这篇博文中对此有一个解释,但我没有看到任何关于这件事的真正结论
角度文档声明该模型是数据的“单真实点”。也许我读了很多(这只是V和C之间值的“真值”吗?),但这表明,如果使用ControllerAs
语法,控制器属性就是模型和“单点真值”
如果这是给定的,并且您希望将所有逻辑抽象到服务中,那么在我看来,您无法摆脱两个非常丑陋的备选方案之一,即保持控制器属性与服务值同步:
myController.data=service.data
。这是可行的,但非常糟糕,因为所有的服务数据都暴露在视图中,而这些精简控制器的作用不就是充当视图的门面吗?或者从另一个角度来看,该服务现在已经成为一个事实上的“胖”控制器,充满了业务逻辑$watch
表达式。这并不理想,因为
- 您向控制器添加了大量样板文件
- 您在代码中显著增加了watch表达式的数量(angular在template controller链接上放置了一个watch,并为中的每个变量添加了控制器服务链接)
编辑:根据答案和一些额外的调查,我收集了我对本文中问题的想法。它包括3种不进行服务绑定的方法(IMHO)和两种可能更接近“正确”方法的方法。服务返回模型。控制器与服务交互以填充视图模型($scope)。视图与视图模型交互以渲染视图 要保持数据同步,您有几个可用选项 选项1:引入一个工厂或服务,其任务是跟踪实例,比如缓存服务。任何需要绑定到视图的实例的控制器都可以从服务请求该实例。这是干净的-不需要显式的监视表达式或非特定的模型绑定 这里有一个例子。假设要跨多个控制器绑定到用户对象 创建用户服务
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];
}
}
});
创建缓存用户服务
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];
}
}
});
在这里,我们利用单例(所有工厂和服务都是单例),并依赖缓存服务来保留模型引用。后一点对于确保视图更改与模型更改同步至关重要
在任何需要缓存用户服务的控制器中使用该服务:
app.controller('ctrl', function($scope, CachedUserService) {
$scope.user = CachedUserService.getUserById(...);
});
选项2:只需在$scope链(即$rootScope)的更高位置存储您希望保持同步的模型
由于原型作用域继承,任何子作用域都能够绑定到作用域链更高的模型。但是,当您在$scope上分配或覆盖模型时,请小心-您可能会无意中破坏模型绑定。要保留引用,请使用
angular。请复制。谢谢您的回答。这就是我一直在做的事情。但我的挫折在于我如何解释Angular docs关于集合上的$watch
es是如何工作的。我已经更新了plunkr以反映这一点——这里提供的简单工厂是缓存服务的代理。对于您描述的用例,我不会设置$watchs。你说得对-有更好的方法确保数据与视图同步(上面列出了两个选项)$手表应该为自定义指令中的链接函数保留,在自定义指令中可能需要对DOM进行操作