AngularJS在连接或断开连接到firebase

时间:2016-06-22 20:23:32

标签: angularjs firebase angularjs-service firebase-realtime-database

我希望在连接或断开连接到firebase服务器时更改图标颜色。我到目前为止:

HTML

<button class="button button-icon ion-cloud" ng-style="dbConnectedStyle"></button>

控制器

firebaseRef.$loaded().then( function() {
  $scope.dbConnectedStyle = {'color': dbConnectStatus.color};
}

服务

.service('dbConnectStatus', function(firebaseRef){
  var status = false;
  var color = 'transparent';
  var connectedRef = firebaseRef.child(".info/connected");
  connectedRef.on("value", function(snap) {
    status = snap.val();
    if (status) {
      color = 'lightgrey';
      console.log("Connected to DB (" + color + ")" );
    } else {
      color = 'transparent';
      console.log("Disonnected to DB (" + color + ")" );
    }
  });
  return {
    'boolean': status,
    'color': color
  }
})

它第一次改变颜色。但是当它断开连接时它没有改变......似乎它不是双向绑定到服务。我如何实现这一目标?

更新

尝试将服务作为对象进行引用,而不是按照优秀教程A Tale of Frankenstein and Binding to Service Values in Angular.js

中的说明进行基元分配

我将代码更改为以下

HTML

<button class="button button-icon ion-cloud" 
        ng-style="dbConnectionStatus.connectionStyle">
        </button>

服务

.service('dbConnectStatus', function(firebaseRef, $rootScope){
  this.status = false;
  var styles = {
    'offlineStyle': {'color': 'red'},
    'onlineStyle': {'color': 'lightgrey'}
  };
  this.connectionStyle = styles.offlineStyle;

  firebaseRef.child(".info/connected")
    .on("value",
      function(snap) {
        this.status = snap.val();
        if (snap.val()) {
          console.log("Connected to DB.");
          this.connectionStyle = styles.onlineStyle;
          console.log(this.connectionStyle);
        } else {
          console.log("Disconnected to DB.");
          this.connectionStyle = styles.offlineStyle;
          console.log(this.connectionStyle);
        }
        console.log(this.status);
        $rootScope.$broadcast('dbConnection:changed');            
      }
    );

})

控制器

$scope.dbConnectionStatus = dbConnectStatus;
      $scope.$on('dbConnection:changed', function() {
        console.log("'on(...)' called. This is the $scope.dbConnectionStatus.connectionStyle:");
        $scope.dbConnectionStatus = dbConnectStatus;
        console.log($scope.dbConnectionStatus.connectionStyle);
        console.log("This is the dbConnectStatus.connectionStyle:");
        console.log(dbConnectStatus.connectionStyle);
      });
      $rootScope.$watch('dbConnectStatus', function (){
        $scope.dbConnectionStatus = dbConnectStatus;
      });
      //$rootScope.$apply();

然后我重新加载代码并获得此控制台消息

First time load

然后我关闭了连接

Internet connection off

然后我打开连接

Internet connection on

我很清楚,服务dbConnectionStatus不会按照我的预期更新为全局变量。我假设在应用程序加载时调用一次服务,并且将范围变量分配给服务(对象)不是调用而是引用...

我做错了什么?

3 个答案:

答案 0 :(得分:5)

我使用@helper ChangedDisplay(string changed) { if (string.IsNullOrEmpty(changed) || changed.Trim().ToLower() == "n/a") { @:n/a } else { var rows = changed.Split(';'); <ul> @foreach (var row in rows) { var columns = row.Split(':'); <li> @(columns.First()): @if (columns.Last().Contains("|||")) { @ChangedDisplay(columns.Last().Trim('|')) } else { @columns.Last() } </li> } </ul> } } $emitjsFiddle中工作,以处理服务中的状态更改。主要问题是当上线时角度绑定不能正常工作,所以我需要使用$on强制进行角度循环。

我开始研究代码的第一个版本,但进行了一些重构。您可以在jsFiddle上找到完整代码,但服务和控制器如下所示:

服务

$scope.$apply()

控制器

.service('dbConnectStatus', function($rootScope){
  var status = false;
  var color = 'red';
  var self = {      
        startWatchingConnectionStatus: function(){
        var connectedRef = firebase.database().ref().child(".info/connected");
        connectedRef.on("value", function(snap) {
            console.log(snap.val());
            status = snap.val();
            if (status) {
                color = 'blue';
                console.log("Connected to DB (" + color + ")" );
            } else {
                color = 'red';
              console.log("Disonnected to DB (" + color + ")" );
              }
            $rootScope.$emit('connectionStatus:change', {style: {'color': color}, status: status}});
        });
      },
      getStatus: function(){
        return status;
      },
      getColor: function(){
        return color;
      }
  };
  return self;
})

如果有任何事情尚不清楚,请告诉我。

答案 1 :(得分:0)

受到@adolfosrs的启发,我发现以下解决方案适合我。

<强>服务

.service('dbConnectStatus', function(firebaseRef, $rootScope){
  // Initial setup
  var styles = {
    'offlineStyle': {'color': 'red'},
    'onlineStyle': {'color': 'skyeblue'}
  };

  // Functions to switch status
  var offline = function () {
    this.boolean = false;
    this.style = styles.offlineStyle;
  }
  var online = function () {
    this.boolean = true;
    this.style = styles.onlineStyle;
  }

  var get_status = function(){
    return {
      boolean: this.boolean,
      style: this.style
    }
  }

  // Read the firebase info and update when changed
  firebaseRef.child(".info/connected")
    .on("value", function(snap) {
        if (snap.val()) {
          online();
        } else {
          offline();
        }
        $rootScope.$emit('dbConnection:changed', get_status() );
    });
})

<强>控制器

// Hide it before the status is known.
$scope.dbConnectionStatus = {'color': 'transparent'}; 
// Getting and reading status changes
$rootScope.$on('dbConnection:changed', function(event, status) {
    $scope.dbConnectionStatus = status.style;
    $scope.$apply();
  });

答案 2 :(得分:0)

您应该能够通过将颜色存储在服务中的对象中并从控制器引用它来简单地工作。 e.g。

查看

<button class="button button-icon ion-cloud" ng-style="dbStatusService.style"></button>

控制器

$scope.dbStatusService = dbConnectStatus;

服务

.service('dbConnectStatus', function(firebaseRef){
    var status = false;
    var style = {color: 'transparent'};
    var connectedRef = firebaseRef.child(".info/connected");
    connectedRef.on("value", function(snap) {
        status = snap.val();
        if (status) {
            style.color = 'lightgrey';
        } else {
            style.color = 'transparent';
        }
    });
    return {
        'boolean': status,
        'style': style
    }
});