2016-12-03 25 views
0

以下是爲用戶配置文件數據(如名稱,照片)向MyApp的API發送http請求以更新導航欄的代碼。Angular not updating服務變量

var app = angular.module('MyApp', ['ng']); 

app.controller('navBarController', function($scope, $userProfile) { 
    $scope.userProfile = $userProfile; 
    console.log("$userProfile: " + JSON.stringify($userProfile)); 

    setTimeout(function() { 
     console.log("$userProfile: " + JSON.stringify($userProfile)); 
    }, 3000); 

}); 

app.factory('$userProfile', function($http) { 
    var profile = null; 
    $http. 
     get('/api/v1/me'). 
     success(function(data) { 
      profile = data; 
      console.log("profile after get: " + JSON.stringify(profile)); 
     }). 
     error(function(data, $status) { 
      if ($status === status.UNAUTHORISED) { 
       profile = null; 
       console.log("profile if error: " + JSON.stringify(profile)); 
      } 
     }); 

    console.log("profile (finally): " + JSON.stringify(profile)); 
    return profile; 
}); 

app.directive('navBar', function() { 
    return { 
     controller: 'navBarController', 
     templateUrl: 'templates/nav_bar.html' 
    } 
}); 

我控制檯日誌記錄,以檢查我收到了意想不到的效果和日誌如下:

輪廓(最後):空

$ USERPROFILE:空

獲取後的個人資料: {「photo:」http://localhost:3000/img/1023.jpg「,」name「:」Utkarsh Gupta「}

$ USERPROFILE:空

前兩個數封郵件是顯而易見的$http.get()是異步的配置文件是空作爲函數的定義開始。但$http.get()函數成功返回後,配置文件var得到更新,如第三次日誌消息中所示,但$userProfile服務繼續爲空。

+1

$保留給角特定變量...不是一個好的做法是使用$用戶做出變量 –

回答

0

而是在頂部初始化輪廓爲空的,你必須初始化它:

var profile = {}; 

然後釘在該空配置文件對象您的API返回的數據,如:

$http. 
     get('/api/v1/me'). 
     success(function(data) { 
     //like this 
      profile.data = data; 
     }) 

在您的代碼中,當$ userProfile-service函數完成時,它將簡要返回爲空。即使$ http.get請求完成後,您的$ userProfile也具有相同的空值,因爲現在更新的配置文件變量不再可訪問,因爲它超出了範圍。但是,如果初始化並返回配置文件作爲對象,則即使在函數返回後也可以訪問該對象,因爲在JavaScript中通過引用傳遞對象爲。然後,您可以按照您現在的操作方式訪問控制器中的配置文件對象的內容,因爲現在$ userProfile與您在上面聲明的同一個確切的配置文件對象不再是null,並且該配置文件的任何更新都可以在整個代碼中的任意位置將被反映在對象被訪問的任何地方。

1

看起來您的服務沒有注入控制器。

你試過這種方式嗎?

app.controller('navBarController', ["$scope", "$userProfile", function($scope, $userProfile) {}]

這裏舉例: https://docs.angularjs.org/guide/services

+0

我已經宣佈它在我展示的代碼。 – Utkarsh

+1

另外請務必閱讀關於如何編寫Angular的John Papa styleguide。 https://github.com/johnpapa/angular-styleguide/tree/master/a1 – jediz

1

在你的服務,你已經宣佈var profile = null;並觸發$http API調用然後立即返回變量profilenull在返回的時間,以後你是一旦api得到響應就更新變量,並且您期待它應該傳播到控制器,而不是這種情況。

隨着服務在本質上是singleton,例如將一次性創建 從未創建/更新。

因此,您的代碼不是推薦使用的服務。我更新了下面的代碼,其中服務將返回一個名爲load的方法來調用從控制器觸發的API,其中$scope可以直接分配響應數據。

var app = angular.module('MyApp', ['ng']); 

app.controller('navBarController', function($scope, $userProfile) { 
    $userProfile.load(). 
     success(function(data) { 
      $scope.userProfile = data; 
      console.log("profile after get: " + JSON.stringify($scope.userProfile)); 
     }). 
     error(function(data, $status) { 
      if ($status === status.UNAUTHORISED) { 
       $scope.userProfile = null; 
       console.log("profile if error: " + JSON.stringify($scope.userProfile)); 
      } 
     }); 

}); 

app.factory('$userProfile', function($http) { 
    var getProfile = function() { 
     return $http. 
     get('/api/v1/me'); 
    }; 

    //console.log("profile (finally): " + JSON.stringify(profile)); 
    return { 
     load: getProfile 
    }; 
}); 

app.directive('navBar', function() { 
    return { 
     controller: 'navBarController', 
     templateUrl: 'templates/nav_bar.html' 
    } 
}); 

注意:另外,請不要使用$前綴服務,變量控制的名字,因爲這是保留給AngularJS和可能產生衝突 當您使用相同的名稱作爲AngularJS reservered關鍵字/服務。

1

您需要先修復您的服務(工廠)。它需要返回並反對。現在你只是在你的服務中運行異步代碼,沒有辦法讓你的控制器使用它。第二次,你修復你的服務(看下面的代碼),你需要創建一個函數來獲取用戶配置文件。用戶配置文件函數需要返回一個承諾,因爲您正在使用異步代碼。再次看下面的代碼,我希望它有幫助。

var app = angular.module('MyApp', ['ng']); 

app.controller('navBarController', function($scope, $userProfile) { 

    $userProfile.get().then(function(response){ 
     $scope.userProfile = response; 
    }); 

    setTimeout(function() { 
     console.log("$userProfile: " + JSON.stringify($userProfile)); 
    }, 3000); 

}); 

app.factory('$userProfile', function($http) { 

    var self = {}; 

    self.get = getProfile; 

    return self; 

    function getProfile(){ 

     var profile = null; 

     return $http.get('/api/v1/me') 
      .success(function(data) { 

       return data.data; 

      }) 
      .error(function(data, $status) { 

       if ($status === status.UNAUTHORISED) 
        return profile; 

      }); 

    } 
});