angularjs - 将服务数据绑定(bind)到 Angular View 的最佳实践是什么(1.3)

标签 angularjs

我是 Angular 新手,但在编码方面有相当多的经验,并且在“正确” View 中获取数据绑定(bind)时遇到一些问题。

我的方法大致是:

我遇到的困惑是,没有显式的 $scope 对象会混淆 MVC 哲学中的模型。有一个passing comment在博客文章中,我看到了这一点,但我没有看到关于此事的任何真正的结论。

Angular 文档指出该模型是数据的“单一事实点”。也许我读得太多了(这只是 V 和 C 之间值的“真相”吗?)但这表明,如果您使用 ControllerAs 语法,则 Controller 属性是模型——以及“单点真理”。

如果这是给定的,并且您希望将所有逻辑抽象到服务中,那么在我看来,您无法摆脱将 Controller 属性保留在两个相当难看的替代方案中的一个与服务值(value)观同步:

  1. 向 View 公开服务。即myController.data = service.data。这可行,但相当粗糙,因为所有服务数据都暴露给 View ,而这些瘦 Controller 的目的不是充当 View 的外观吗?或者换个 Angular 来看,该服务现在已经成为一个事实上的“胖” Controller ,充满了业务逻辑。
  2. 仅公开您希望 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/

相关文章:

javascript - 用 Electron 下载游戏/用 Electron 检测游戏版本

javascript - Ng-Paste - 以数组或列表的形式访问粘贴的数据

angularjs - 集成karma-runner和cucumberjs

javascript - 在推送项目之前检查属性值是否存在

javascript - AngularJS + Angular Strap - 如何根据单击的按钮向模式添加动态内容?

javascript - 无法读取未定义的属性 'toLowerCase' (Angularjs/JavaScript/Json)

javascript - 从 Angular 范围内的数组获取所有对象

javascript - 如何将 html 字符串打印为 html

javascript - 复杂对象的 Angular 自定义过滤器

javascript - Angular - 将 ng Strict 与 Google Chart 库一起使用