父母和子女控制器数据设计

时间:2013-02-21 21:16:20

标签: angularjs

好的,让我们设置一个场景。

情境: 你有一个内容控制器。这个内容可能是照片,博客文章,等等。现在,在这个内容的html中,你有一个Comment控制器。 CommentController的工作是加载注释,允许注释提交等。但是,此控制器的功能取决于它的父级。毕竟,如果没有父母,你在评论什么?

问题: 所以说,让我们介绍一个问题。 ContentController需要从服务器请求信息以填充自身,其中一部分是唯一ID。现在,还有其他方法可以解决这个问题,例如使用url-state作为唯一ID,但这是解释此问题的最佳方法。

将唯一ID从服务器加载到ContentController中。然后它使用此ID和实际内容填充其$ scope。另一方面,CommentController想要加载它自己的资源,但它的资源加载都依赖于父ContentController的加载数据。由于两个控制器同时加载,我们需要一种方式来发信号或延迟执行子CommentController的执行。否则,它将尝试从服务器请求有关不存在的唯一内容ID的注释。

问题: 这是一个非常基本的问题,有许多明显的答案。然而,我的问题是这样的角度怎么样?对于最适合“角度方式”的解决方案是什么。

最明显的方法是简单地拥有一个活动创建者/消费者。 Angular有多种方法可以解决这个问题。比如服务,$scope.promise = promise,解决承诺,$scope.$broadcast等等。对我而言,这些设定的设计感觉......笨重......它也感觉紧密耦合。我希望我的ContentController不会被其中可能包含的内容所困扰。

另一种方法是$watch所需变量的范围,例如$scope.$watch('content.uid', function(newValue) {})。与上述解决方案相比,这感觉更好,耦合更少。但至少对我来说仍然不完美。

我觉得最好的解决方案是我不知道如何实现的解决方案。我希望控制器能够..延迟,儿童控制器,如果(父)正在做一些异步的事情。我觉得这比一个事件更好,因为它是隐含的简单。它本质上仍然是一个事件广播,但希望语法是干净的,因为只有一个“事件”。它不完整或完整。虽然,我不确定如果不使用上述某种方法之一,这样的事情是否可行..那么无论如何都会实现这个目标吗?

无论如何,自从我几周前开始学习Angular以来,这一直是我脑子里一直存在的问题。任何有关该主题的见解将不胜感激。

感谢阅读!

1 个答案:

答案 0 :(得分:7)

Angular很容易避开设计,或者为了你所描述的目的而变量的$watch,特别是因为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; }
});

通过这种方式解决问题,控制器只负责协调和响应视图。是的,我必须$watch提供Selected服务,但这样的事情或多或少是不可避免的。但是,它会使您无法直接观看数据,例如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', function($scope, 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($scope, Selected) {
  $scope.Selected = Selected;

  $scope.$watch('Selected.thing', function(thing) {
    $scope.thing = thing;
    $scope.comments = thing.CommentResource.query({id: thing.id});
  });
});

摘要

我知道在使用Angular时感觉“恢复到旧方式”时可以获得的icky感觉。

我认为诀窍是从你的控制器中除了协调之外的一切,然后即使你必须使用某些事件或分配一堆$watches,你仍然会在松散耦合中这样做方式。

这只是我的两分钱,希望它有用。