如何使用 Angular 1.x 服务从另一个组件更新一个组件?

Posted

技术标签:

【中文标题】如何使用 Angular 1.x 服务从另一个组件更新一个组件?【英文标题】:How to use angular 1.x services to update one component from another? 【发布时间】:2018-03-23 04:47:30 【问题描述】:

所以我有一个父组件,其中包含大量较小的组件。一般的想法是我需要一个组件来接收输入中的数据并将其显示在另一个组件上。这就是我所拥有的,它不太管用,之后有更多关于问题的详细信息:

const app = angular.module('app', []);

app.service('dataService', function() 
  let data = 
    key1: "",
    key2: "",
    key3: 
      key4: 0,
      key5: 0
    
  

  this.getKey1 = function() 
    return data.key1;
  

  this.updateKey1 = function(str) 
     data.key1 = str;
  


app.component('display', 
  controller: displayController,
  template: '<p> keyOne </p>'
);

app.component('input', 
  controller: inputController,
  template: '<input ng-model="$ctrl.key1" ng-change="sendKey1()">'


function displayController($scope, dataService) 
  const vm = this;
  const self = $scope;
  vm.$onInit = onInit;
  function onInit() 
    self.keyOne = dataService.getKey1();
  


function inputController($scope, dataService) 
  const vm = this;
  const self = $scope;
  vm.$onInit = onInit;
  function onInit() 
    self.sendKey1 = function() 
      dataService.updateKey1(vm.key1)
  

所以更新有效,但它没有将它传递给显示组件。如果我在更新数据对象后记录它是正确的,但它不会显示在视图中。

【问题讨论】:

【参考方案1】:

看看A Tale of Frankenstein and Binding to Service Values in Angular.js。

以下是正在发生的事情的简要总结:

    displayController 执行 self.keyOne = dataService.getKey1()。这会将一个空字符串分配给$scope.keyOne。 在视图中,表达式 keyOne 监视$scope.keyOne 的变化。它最初的计算结果为 "",因此视图中存在一个空字符串。 inputControllerdataService.data.keyOne 更改为某个值,例如 hello world。 在视图中,表达式 keyOne 再次评估$scope.keyOne 作为摘要循环的一部分进行更改。 问题: $scope.keyOne 仍然是一个空字符串! displayController 不知道从 dataService.data.keyOne 获取最新值。

幸运的是,修复很简单。您只需要获取对 data 对象的引用,以便在观察更改时正确评估 data.keyOne

app.service('dataService', function() 
  let data = 
    key1: ""
  

  //Expose the data object
  this.getData = function() 
    return data;
  


app.component('display', 
  controller: displayController,
  //Evaluate the current value of keyOne in the data object
  template: '<p> data.keyOne </p>'
);

function displayController($scope, dataService) 
  const vm = this;
  const self = $scope;
  vm.$onInit = onInit;
  function onInit() 
    //Get a static reference to the data object.
    //The data object itself shouldn't change, but its properties will.
    self.data = dataService.getData();
  

【讨论】:

【参考方案2】:

你正在更新一个字符串 data.key1 = str;

let data = key1: "", key2: "", key3: key4: 0, key5: 0

Angular 不绑定组件之间的字符串,只绑定对象。

看这里https://plnkr.co/edit/wfwyyGpcMKOSHGFdg2DS?p=preview

var app = angular.module('plunker', ['ngRoute', 'ngAnimate', 'ngSanitize']);

app.service('dataService', function() 
  let data = 
    key1: "",
    key2: "",
    key3: 
      key4: 0,
      key5: 0
    
  

  this.getData = function() 
    return data;
  

  this.updateKey1 = function(str) 
    data.key1 = str;
  
);



app.component('inputc', 
  controller: inputController,
  template: '<input ng-model="$ctrl.key1" ng-change="sendKey1()">'
);

app.component('display', 
  controller: displayController,
  template: '<p> data.key1 </p>'
);

function displayController($scope, dataService) 
  const vm = this;
  const self = $scope;
  vm.$onInit = onInit;

  function onInit() 
    self.data = dataService.getData();
  


function inputController($scope, dataService) 
  const vm = this;
  const self = $scope;
  vm.$onInit = onInit;

  function onInit() 
    self.sendKey1 = function() 
      dataService.updateKey1(vm.key1)
    
  
<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link href="style.css" rel="stylesheet" />
    <script src="https://code.angularjs.org/1.6.2/angular.js"></script>
    <!-- By setting the version to snapshot (available for all modules), you can test with the latest master version -->
    <!--<script src="https://code.angularjs.org/snapshot/angular.js"></script>-->
    <script src="https://code.angularjs.org/1.6.2/angular-route.js"></script>
    <script src="https://code.angularjs.org/1.6.2/angular-animate.js"></script>
    <script src="https://code.angularjs.org/1.6.2/angular-sanitize.js"></script>    
    <script src="app.js"></script>
  </head>

  <body>
    <inputc></inputc>
    <display></display>
  </body>
  
  

</html>

【讨论】:

【参考方案3】:

看看这篇文章:https://www.aurorasolutions.io/blog/angularjs-cross-component-communication/

很好地解释了你的问题。

希望对你有帮助!

【讨论】:

以上是关于如何使用 Angular 1.x 服务从另一个组件更新一个组件?的主要内容,如果未能解决你的问题,请参考以下文章

Angular2从另一个组件访问变量

如何从另一个组件调用一个函数,同时保持另一个组件在 Angular 中的通用性?

如何从另一个组件重新渲染特定组件模板?角 2

从另一个组件打开 angular Powered bootstrap 模态

如何从另一个组件返回到另一个组件而不以角度重新加载组件?

Angular 2 从另一个组件访问组件