2014-09-10 52 views
2

編輯:如問,我會更有效地解釋一下!查看更新無處不在,但在當前控制器 - angularJS

最近我一直坐在一個惱人的問題面前,這就是說,無論何時我更新指令中的值,控制器我目前不是「in」是唯一需要更新的控制器。

場景示例:配置文件頁面由兩個控制器組成。目前正在顯示用戶名的Navbar_controller:

<div ng-if="Auth.isAuthenticated">Hello, {{Auth.getCurrentUser().name}}</div> 

第二個控制器Profile_controller在這裏更新用戶值。這是在角第一控制器,這將更新CurrentUser一個簡單的函數:

$scope.updateUser = function (type, form) { 
    if (!$scope.modif) 
     return ; 

    $http.put('/api/users/' + Auth.getCurrentUser()._id + '/update', {type:type, modif:$scope.modif}) 
      .success(function (data, status) { 
       $scope.user = Auth.setNewUser(data); 
      }) 
      .error(function() { 
       console.log("error"); 
      }); 
    }; 

當我更新,例如,名稱。我可以看到數據庫已被正確修改。事實上,navbar_controller得到了更新,因爲在div中打印了一個新名稱。但是,Profile_controller沒有得到更新:在配置文件頁面中打印的名稱沒有更改。

下面是兩種基本功能在Auth.service.js:

getCurrentUser: function() { 
    return currentUser; 
    }, 

// 'user' is the data retrieved in http put request dot success 
setNewUser: function(user) { 
     currentUser = user; 
     $rootScope.$broadcast(); // Navbar_controller is updated with or without this line 
     return currentUser; 
    } 

無論如何,如果我看導航欄及其控制器,其被調用Auth.getCurrentUser()的方法,該用戶的值是立即修改。我一直在使用一種醜陋的方法,包括手動修改控制器值或刷新頁面......但這不是要走的路,對吧?

必須有一些東西用「$ rootScope。$ broadcast();」,但我真的是新來的Angular和其他問題在stackoverflow是太具體,以幫助我理解正確。

謝謝!

+0

能否詳細說明一下,實際問題是什麼?當前用戶是否正在上下文中調用您的方法? – 2014-09-10 13:28:53

+0

是你的刷新問題? – V31 2014-09-10 13:36:44

+0

嘗試擴展對象,而不是用新的替換它 – charlietfl 2014-09-10 13:55:35

回答

0

你的問題有點難以理解,但我認爲問題在於你在各種控制器中引用了一個不斷變化的對象。下面是一個例子來解釋:

服務:

var myObject = { ... }; 
return { 
    getObject() { return myObject; } 
    setObject(obj) { myObject = obj; } 
}; 

控制器1:

$scope.myObjA = Service.getObject(); 

控制器2:

$scope.myObjB = Service.getObject(); 

現就初始化兩個控制器將引用相同對象,所以如果你改變了任何一個控制器的屬性(例如$scope.myObjB.name = 'bob';),那麼另一個控制器也會看到這個名字。但是,如果您在控制器中更改了對象本身(例如Service.setObject(newObj);),則控制器將引用新對象,而另一個控制器仍將引用舊對象。

您可以通過在一個容器包裝你的服務對象解決這個問題:

var cont = { 
    user: ... 
}; 

function getContainer() { return cont; } 

function setNewUser(user) { cont.user = user; } 

然後你的控制器內,得到了容器(而不是用戶):

$scope.cont = Service.getContainer(); 

而在HTML中:

<div>{{cont.user.name}}</div> 

現在,當您更新用戶時,所有連接的控制器將被更新。

+0

確實有效!你介意多解釋一下,因爲在我看來,用戶也是一種容器 – Thook 2014-09-10 14:21:41

+0

當兩個作用域綁定到'x'時,如果'x'的任何屬性如'x.name'改變了,那麼它會在兩個範圍上進行更改。但是,如果'x'本身被改變,那麼一個範圍將指向新的'x',另一個範圍將指向舊的'x'。通過在容器中包裝'x''',兩個範圍指向同一個容器,因此更改'x'由兩個範圍反映(因爲容器不會更改)。希望有所幫助(不要忘記標記問題)。 – 2014-09-10 21:31:18

+0

謝謝你的解釋,它確實有幫助。這裏是一個關於範圍繼承的討論,以防某人在這裏進入:http://youtu.be/ZhfUv0spHCY?t=30m1s – Thook 2014-09-11 09:32:53

0

嗯,我會嘗試更改並將用戶信息存儲在$ rootScope中,因爲您的方案可能非常合適。

getCurrentUser: function() { 
    $rootScope.currentUser===undefined ? 'no User': $rootScope.currentUser; 
    }, 

setNewUser: function(user) { 
     $rootScope.currentUser = user; 
     //$rootScope.$broadcast(); no need to broadcast 
     return getCurrentUser(); 
    } 

這樣,currentUser將根據需要在不同的範圍內更新!

我還要舉AnuglarJs FAQ關於到$ rootscope:

$ rootScope存在,但它可用於邪惡

偶爾有要進行全局數據塊到 整個應用程序。對於這些,您可以注入$ rootScope並在 上設置值,就像其他任何範圍一樣。由於作用域繼承自根作用域,因此這些值將可用於像ng-show之類的 指令所附的表達式,就像本地$ scope中的值一樣。

當然,全局狀態很糟糕,你應該謹慎使用$ rootScope, 就像你會(希望)用任何語言的全局變量一樣。 特別是,不要將它用於代碼,只用於數據。如果您試圖在上放置一個$ rootScope函數,那麼將其放入 服務中幾乎總是更好,該服務可以在需要的地方注入,並且更容易測試 。

相反,不要創建一個服務,其唯一的目的是在 存儲和返回數據位。

+0

確實,但我聽說使用$ rootScope是一種不好的做法。你認爲它應該用於這樣一個重要的變量,因爲用戶在我的應用程序中隨處可見? – Thook 2014-09-10 14:26:38

+0

對於這種情況,這不是一個壞習慣,我更願意在rootcope中擁有用戶信息,而不是每次需要時複製信息素材,這對於這樣一個簡單任務來說更具有樣板代碼,更改用例用戶的信息不會經常發生 – 2014-09-10 14:34:09

+0

您不應該使用'$ rootScope'來存儲任何內容。服務更適合這種情況。 – 2014-09-10 21:34:20

相關問題