资讯专栏INFORMATION COLUMN

[译] Controller间的数据共享?最佳实践:使用Service

Salamander / 3170人阅读

摘要:共享数据的最佳策略是什么呢用一些{{BANNED}}的控制器继承方案吗当然不是,最简单容易的方式就是使用服务。概括创建一个服务去存放你的数据,并给数据创建和的方法。

原文链接 : Sharing Data Between Controllers? Best Practice: Use a Service
原文作者 : DAVE CEDDIA
译者 : 李林璞(web前端领域)
译者注:翻译如有疏漏,欢迎指出!感谢!转载请保留此头部。

Angular开始起来简单易用,甚至说神奇。“哇哦!双向绑定!”

你会迫不及待地去构建你的杰作,直到碰到钉子:你正在像网上每个人建议的那样去构建一个独立的组件,但怎么和其他组件共享数据呢?

或许你在不同的路由里有两个视图都需要访问某些状态变量,又或者你有三个分离的组件需要访问同样的一堆数据。

共享数据的最佳策略是什么呢?用一些{{BANNED}}的控制器继承方案吗?

当然不是,最简单容易的方式就是使用服务(service)。

问题

假设有两个并排的面板,每个面板代表一个指令(directive):

下面是面板1的代码:

angular.directive("paneOne", function() {
  return {
    restrict: "E",
    scope: {},
    template: [
      "
", "", "", "
" ].join(""), controllerAs: "p1", controller: function() { var vm = this; vm.text = ""; vm.addToList = function() { // TODO: add to the list in Pane 2 somehow vm.text = ""; }; } }; });

面板2的:

angular.directive("paneTwo", function() {
  return {
    restrict: "E",
    scope: {},
    template: [
      "
    ", "
  • {{ item }}
  • ", "
" ].join(""), controllerAs: "p2", controller: function() { var vm = this; // TODO: get this list of items from Pane 1 somehow vm.listItems = []; } }; });

我们想要实现的是在面板1的输入框中输入某些东西,然后点击按钮 “Add To List”, 这条内容就会在面板2的列表中出现。

创建一个服务保持共享状态

为了在两个甚至更多的控制器间共享数据,创建一个服务去扮演中间件的角色。这样可以使控制器(或组件)保持松散耦合:它们不需要知道其他的控制器(或组件)是怎么样的,它们只需要知道数据源 - 你创建的中间件服务。

angular.factory("sharedList", function() {
  var list = [];

  return {
    addItem: addItem,
    getList: getList
  };

  function addItem(item) {
    list.push(item);
  }

  function getList() {
    return list;
  }
}); 

上面这个服务非常简单,调用 addItem 把数据放到列表里,然后调用 getList 获取整个列表。这真的很简单,甚至不需要去移除或者清空列表项,看到这个方法的简便之处了吧。

在任何需要的地方注入服务

既然我们已经创建好了我们的服务,我们就需要在任何需要访问或修改数据的地方去注入它了。

先从面板1的控制器开始:

// Inject sharedList
controller: function(sharedList) {
  var vm = this;
  vm.text = "";
  vm.addToList = function() {
    // Stuff the item into the shared list
    sharedList.addItem(vm.text);
    vm.text = "";
  };
}   

然后是面板2的控制器,获取数据:

// Inject sharedList
controller: function(sharedList) {
  var vm = this;
  // Read the data
  vm.listItems = sharedList.getList();
}    

从JSBin里看看运行情况。

但不需要观察器(watchers)吗?

当我写到这儿的时候,我非常确定面板2中的列表在我添加一些观察器前不会自动更新

但是接下来当我把代码放到 JSBin 里的时候...你瞧,它竟然可以更新!为什么呢?

ng-repeat 给循环的数组设置了观察器。

点击 “Add To List” 触发了一个消化周期 (digest cycle),它就会重新检测 ng-repeat 的观察器。

因为 sharedData.getList() 返回了一个数组的引用,观察器就会看到 p2.listItems 已经发生了变化。这里是关键:如果 getList 返回一个不同于由 addToList 更改的数组,这就不会触发更新了。

所以:这种通信方式可以在没有观察器的情况下完美运行。但如果你发现失败了的话,检查一下你是怎么传递数据的,或许你需要明确地创建一个观察器检测变化。

概括

创建一个服务去存放你的数据,并给数据创建 gettersetter 的方法。

在任何需要这个数据的地方注入这个服务。

这几乎就是全部内容了(除非你需要观察器 - 这种情况下,你还是添加一个吧)。

感谢阅读!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/86400.html

相关文章

  • []Express应用结构的最佳实践

    摘要:为应用增加新的特性和处理新的情况可能都会改变文件的结构。写一个模板的最佳实践是,不要在模板中处理数据。在上面这四个文件夹中,主要的测试代码将是单元测试,这意味着你需要将被测试的代码与应用分离开来。 前言 Node和Express并不严格要求它的应用的文件结构。你可以以任意的结构来组织你的web应用。这对于小应用来说,通常是不错的,十分易于学习和实验。 但是,当你的应用在体积和复杂性上都...

    dreamans 评论0 收藏0
  • Yii2.0框架 MVC 最佳实践

    摘要:框架最佳实践最佳实践在设计良好的应用中,控制器很精练,包含的操作代码简短如果你的控制器很复杂,通常意味着需要重构,转移一些代码到其他类中。层业务逻辑层框架由,,组成,执行流程一般是在访问获取数据,通过渲染页面。 Yii2.0框架 MVC 最佳实践 Controller最佳实践 在设计良好的应用中,控制器很精练,包含的操作代码简短; 如果你的控制器很复杂,通常意味着需要重构, 转移一些代...

    keithxiaoy 评论0 收藏0
  • 】缓存的最佳实践以及max-age的陷阱

    摘要:可能会延长这些的寿命假设你有以下的这个缓存了和如果命中了缓存,就从缓存中取,否则发起网络请求如果我们更改了,我们会修改中的版本号,触发的更新。 本文翻译自:https://jakearchibald.com/201...这是一篇2016年的老文章。作者是Chrome浏览器的开发成员。 本文首发于公众号:符合预期的CoyPan 使用正确的缓存可以带来巨大的页面性能上的收益,节省带宽,减...

    mist14 评论0 收藏0
  • Spring Boot 最流行的 16 条实践解读!

    摘要:来源是最流行的用于开发微服务的框架。以下依次列出了最佳实践,排名不分先后。这非常有助于避免可怕的地狱。推荐使用构造函数注入这一条实践来自的项目负责人。保持业务逻辑免受代码侵入的一种方法是使用构造函数注入。 showImg(https://mmbiz.qpic.cn/mmbiz_jpg/R3InYSAIZkHQ40ly9Oztiart2lESCyjCH0JwFRp3oErlYobhibM...

    Ethan815 评论0 收藏0
  • Kubernetes Deployment 的安全最佳实践

    摘要:今天的文章由来自的和撰写,在不同用户案例中搜集到的数据基础上,描述了的安全最佳实践。在谷歌上,我们的用来部署我们的服务。实施连续安全缺陷扫描容器可能包含过时的已知缺陷的程序包。谷歌云平台的用户能够从自动防火墙规则中受益,避免跨集群交流。 今天的文章由来自 Aqua Security 的 Amir Jerbl 和 Micheal Chemy 撰写,在不同用户案例中搜集到的数据基础上,描述...

    oysun 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<