场景:
你有一个内容控制器.这个内容可能是照片,博客文章,等等.现在,在这个内容的html中,你有一个Comment控制器. CommentController的工作是加载注释,允许注释提交等.但是,此控制器的功能取决于它的父级.毕竟,如果没有父母,你还在评论什么?
问题:
所以说,让我们介绍一个问题. ContentController需要从服务器请求信息以填充自身,其中一部分是唯一ID.现在,还有其他方法可以解决这个问题,例如使用url-state作为唯一ID,但这是解释此问题的最佳方法.
唯一ID从服务器加载到ContentController中.然后它使用此ID和实际内容填充其$scope.另一方面,CommentController想要加载它自己的资源,但它的资源加载都依赖于父ContentController的加载数据.由于两个控制器同时加载,我们需要一种方式来发信号或延迟执行子CommentController的执行.否则,它将尝试从服务器请求关于不存在的唯一内容id的注释.
题:
这是一个非常基本的问题,有许多明显的答案.然而,我的问题是这样的角度怎么样?什么是最适合“角度方式”的解决方案.
最明显的方法是简单地拥有一个事件创建者/消费者. Angular有多种方法可以解决这个问题.比如一个服务,一个$scope.promise = promise,一个解决承诺,$scope.$broadcast等等.对我来说,这些类似的设计感觉……笨重……它也感觉紧密耦合.我更希望我的ContentController不被其中可能包含或不包含的内容所困扰.
另一种方法是$$观察你想要的变量的范围,例如$scope.$watch(‘content.uid’,function(newValue){}).与上述解决方案相比,这感觉更好,耦合更少.尽管如此,至少仍然不完美.
我觉得最好的解决方案是我不知道如何实现的解决方案.我想一个控制器能够..延迟,儿童控制器,如果它(父母)正在做一些异步的事情.我觉得这比一个事件更好,因为它暗示着简单.它本质上仍然是一个事件广播,但希望语法是干净的,因为只有一个“事件”.它不完整或完整.虽然,我不确定如果不使用上述任何一种方法,这样的事情是否有可能..无论如何都会实现这一点吗?
无论如何,自从我几周前开始学习Angular以来,这一直是我脑子里一直存在的问题.任何有关该主题的见解将不胜感激.
谢谢阅读!
解决方法
也就是说,我使用Angular的次数越多,我就越发现自己将数据操作从控制器中拉出来,并进入为控制器公开“API”的服务和工厂.
例如,假设您有经典列表视图/详细信息视图方案,您可以从列表中选择项目,然后在详细信息视图中显示其信息.
我可能有一个$resource支持的工厂列表和一个仅用于管理所选项目的服务:
app.factory('Thing',function($resource) { return $resource('/things/:id') }); app.service('Selected',function() { this.thing = null; this.select = function(thing) { this.thing = thing; } this.clear = function(thing) { this.thing = null; } });
通过这种方式解决问题,控制器只负责协调和响应视图.是的,我必须观看选定的服务,但这或多或少是不可避免的.但是,它会使您无法直接在数据上观看某些内容,例如uid:
app.controller('List',function($scope,Thing,Selected) { $scope.things = Thing.query(); // assuming something like 'ng-click="select(thing)"' in the view $scope.select = function(thing) { Selected.select(thing); }; }); app.controller('Detail',Selected) { $scope.Selected = Selected; $scope.$watch('Selected.thing',function(thing) { $scope.thing = thing; }); });
然后,假设您需要为所选的“东西”加载评论,您只需使用该功能增强您的Thing工厂:
app.factory('Thing',function($resource) { var Thing = $resource('/things/:id'); Thing.prototype.CommentResource = $resource('/things/:thingId/comments/:id'); return Thing. });
然后使用控制器中的该功能.
app.controller('Detail',function(thing) { $scope.thing = thing; $scope.comments = thing.CommentResource.query({id: thing.id}); }); });
我知道在使用Angular时感觉像“恢复到旧方式”时可以得到的icky感觉.
我认为诀窍是从你的控制器中取出一切而不是协调,然后即使你必须使用一些事件或分配一堆$watch,你仍然以松散耦合的方式这样做.
那只是我的两分钱,希望它有用.