【问题标题】:Angularjs 1.5 - Component Communication using service - Async variable manipulation?Angularjs 1.5 - 使用服务的组件通信 - 异步变量操作?
【发布时间】:2016-11-05 05:00:34
【问题描述】:

我对这个 Angular 组件通信非常陌生。我正在使用 Angular 1.5.X 版本,并且正在使用工厂在组件之间共享数据。我面临一个问题,即服务变量的异步值在特定时间后刷新。

我知道一种解决方案是在非范围变量上设置观察者,但我认为我在这里遗漏了一些重要的东西。各位大佬能分享一下看法吗?

这是 Service.js 代码

Service.$inject = ['$http','$q'];

function Service($http,$q) {

  this.$http = $http;
  this.$q = $q;

};

Service.prototype.getTileCount = 0;

Service.prototype.getTileData = function(Url){

    var deferred = this.$q.defer();

    this.$http.get(Url)
        .success(function(response){
            Service.prototype.getTileCount = response.data.length;
            console.log('data length :', Service.prototype.getTileCount);
        deferred.resolve(response);
    });

    return deferred.promise;
};

这是组件 1 控制器代码

function Component1Controller(Service) {

    this.tileData ={};
    var self = this;

    var promise = Service.getTileData(this.sourceUrl);

      promise.then(function(data) {

        self.tileData = data;
        Service.getTileCount = data.length;
        console.log('This is tileData : '+ Service.getTileCount);
      });

    };

这是组件 2 控制器代码

function Component2Controller(Service) {

  var self = this;

  console.log(Service.getTileCount);
// getting getTileCount = 0; After setting timeout function of 5 second I am able to get getTileCount value

};

【问题讨论】:

    标签: javascript angularjs components angular-services


    【解决方案1】:

    问题是Service.getTileCount 是异步更新的,这就是为什么它一开始是0,然后在某些时候它会改变。我建议您简化服务并始终使用getTileData 方法,这将是单一数据源。实现也会变得更简单:

    function Service($http, $q) {
      this._tileData = null;
      this.$http = $http;
      this.$q = $q;
    }
    
    Service.prototype.getTileData = function(Url) {
    
      if (!this._tileData) {
        this._tileData = this.$http.get(Url).then(function(response) {
          return response.data;
        }.bind(this));
      }
    
      return this._tileData;
    };
    

    注意,它如何在“私有”_tileData 属性中缓存切片响应。现在您可以随时依赖getTileData 方法,无论您何时调用它都会返回数据:

    function Component1Controller(Service) {
    
      this.tileData = {};
      var self = this;
    
      Service.getTileData(this.sourceUrl).then(function(data) {
        self.tileData = data;
        console.log('This is tileData:', self.tileData.length);
      });
    };
    
    function Component2Controller(Service) {
      var self = this;
      Service.getTileData(this.sourceUrl).then(function(data) {
        console.log('tile count', data.length);
      });
    };
    

    在这种情况下,Service.getTileCount 不再需要。

    演示: http://plnkr.co/edit/3zE6VL4emXaLRx2nCRih?p=info

    【讨论】:

    • 感谢您的意见。我尝试了相同的方法,但是从两个组件服务调用中,我都将 this._tileData 的服务设为空。所以我认为我们无法存储 this._tileData 对象值,所以在下一次调用时我们再次获得 null。所以基本上我们两次访问 $http 服务,这不是一个好的解决方案。
    • 当然不,我的解决方案的重点是您永远不会发出一个以上的请求(服务缓存数据),并且无论您从哪个组件请求getTileData,您将始终获得可预测的数据方式。
    • 我在代码中发现了一个错误,请查看更适合您情况的更新版本。
    • 谢谢!这对我有用:) 顺便说一句,如果我有两个组件 A 和 B 并且我需要在两个组件之间传递对象,那么除了服务/工厂之外,这应该是最好的方式。我了解继承范围和广播/发射不是一个好习惯。我尝试了父子组件关系,但感觉很难实现。再次感谢您的帮助:)
    • 建立这种通信的最佳方法是使用父组件控制器并使用绑定将相同的对象绑定到需要它的每个组件。 <one data="$ctrl.data"></one><two data="$ctrl.data"></two>.
    猜你喜欢
    • 2017-01-21
    • 1970-01-01
    • 2014-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-15
    • 1970-01-01
    相关资源
    最近更新 更多