在Angular(1.3)

时间:2015-06-25 12:33:21

标签: angularjs

我是Angular的新手,但在编码方面有相当多的经验,并且在“正确”的视图中获取数据绑定时遇到了一些麻烦。

我的方法很广泛:

我遇到的困惑是,没有明确的$scope对象会混淆MVC哲学中的模型。在博客文章中有passing comment这个效果,但我没有看到任何真正的结论。

Angular Docs声称该模型是数据的“单一事实”。也许我对此有很多了解(它只是V和C之间值的“真实”吗?)但这表明,如果你使用ControllerAs语法,那么控制器属性就是模型 - 和“单点真相”。

如果这是给定的,你想要将所有逻辑抽象为服务,那么正如我所看到的,你无法摆脱两个相当丑陋的选择之一来保持控制器属性与服务值同步:

  1. 将服务公开给视图。即myController.data = service.data。这是有效的,但是非常严重,因为所有服务数据都暴露在视图中,并且这些瘦控制器不能充当视图的外观?或者从另一个角度来看,该服务现在变成了一个充满业务逻辑的事实'胖'控制器。
  2. 仅展示您希望视图访问的服务中的元素,但在每个元素上放置$watch个表达式。这不太理想,因为
    • 您向控制器添加了大量样板
    • 您在代码中显着增加了监视表达式的数量(角度将监视放在模板&lt; - &gt;控制器链接上,然后添加控制器&lt; - &gt;服务链接;对于每个变量)< / LI>
  3. 这些是否真的是在Angular 1.3中执行此操作的唯一方法?或者有什么(更优雅)我错过了?

    修改:根据答案和其他一些调查,我已经在plunkr收集了我对这个问题的看法。它涵盖了3种方式(恕我直言)不进行服务绑定,以及两种可能更接近“正确”方法的方式。

1 个答案:

答案 0 :(得分:2)

服务返回模型。控制器与服务交互以填充视图模型($ scope)。视图与视图模型交互以呈现视图。

为了保持数据同步,您可以选择一些选项。

选项1:引入工作或服务,其工作是跟踪实例 - 如缓存服务。任何需要绑定到视图的实例的控制器都可以从服务中请求它。这很干净 - 不需要明确的监视表达式或非特定的模型绑定。

这是一个例子。假设您要跨多个控制器绑定到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];                 
         }
     }
});

在这里,我们正在利用单例(所有工厂和服务都是),并依靠缓存服务来保留模型引用。后一点对于确保视图更改与模型更改同步至关重要。

在需要它的任何控制器中使用缓存用户服务:

app.controller('ctrl', function($scope, CachedUserService) {
     $scope.user = CachedUserService.getUserById(...);
});

选项2:只需存储您希望保持同步的模型,高于$ scope链(即$ rootScope)

app.controller('ctrl', function($scope, $rootScope, UserService) {
      $rootScope.user = UserService.getUserById(...);
} 

由于原型范围继承,所有子范围都能够绑定到范围链上方的模型。但是,在$ scope上分配或覆盖模型时要小心 - 您可能会无意中破坏模型绑定。要保留引用,请改用angular.copy