将对象添加到$ scope的两种方法,只有一种方法有效

时间:2014-09-08 08:52:34

标签: javascript angularjs

我有一个用户服务负责身份验证。

在html中我有:

<div ng-show="user.authenticated">Hi {{user.username}}!</div>

控制器设置范围如下:

$scope.user = userService;

这很棒!如果我正在重新加载html页面,div会暂时隐藏,直到已登录的用户进行身份验证。

但是,如果我尝试在控制器中的$ scope上设置用户对象,如下所示:

$scope.user = {
  username: userService.username,
  authenticated: userService.authenticated
};

如果我重新加载页面,那么它不再起作用,即使用户已登录,也不会显示div,如上例所示。这怎么不行?

编辑:我将添加控制器(或至少是控制器中有趣的部分):

angular.module('app.controllers')
  .controller('NavCtrl', ['$scope','$rootScope','$location','userService','alertService',
   function($scope,$rootScope,$location,userService,alertService) {
//    $scope.user = userService;  // This works (but is now commented out)

// The following does not work if the user reloads this page
// The view is only updated with username when (after a few milliseconds)
// userService has talked with the server and gotten the user-details...    
      $scope.user = {
          username: userService.username,
          authenticated: userService.authenticated
        };

   }]);

登录后重新加载html很重要,否则userService已经设置了用户详细信息。所以当设置视图时(在页面重新加载之后),userService中没有可用的用户信息,这在重新加载后只有一小段时间可用....

编辑2:我尝试第二个变体的原因是因为我有一个页面,其中包含具有各种属性的对象,并且用户名只是所需属性之一。这可以正常工作,直到用户可能重新加载页面。

编辑3:我已经改变了2ooom的小提琴,使其更像我的情况,请参阅http://jsfiddle.net/utphjuzy/1/

3 个答案:

答案 0 :(得分:1)

这与Angular的绑定机制如何工作(以及绑定如何工作)有关。

当你执行$scope.user = userService;之类的操作时,实际上是将属性user绑定到对象 userService。这意味着两个属性都将指向相同的内存中可变对象引用。如果该对象的属性发生变化,那么两个&#34;指针&#34;会注意到更改(在$scope.user的情况下,将强制重新渲染)。

但是,如果你这样使用它:

$scope.user = {
  username: userService.username,
  authenticated: userService.authenticated
};

您正在创建一个全新的user 对象,并且您要分配其属性不是按引用而是按值,因为JavaScript字符串,数字和布尔值是不可变的因此不能通过引用分配。最终,这意味着Angular将无法跟踪这些属性的变化。

执行所需操作的一种方法是在包含任何需要绑定的数据的服务上使用模型 对象。如此Plunker所示。

答案 1 :(得分:0)

您正在设置永远不会更新的值。你的控制器只运行一次,所以:

  $scope.user = {
      username: userService.username,
      authenticated: userService.authenticated
    };

设置为创建控制器时的任何值。由于我猜测您的用户服务使用AJAX获取详细信息,因此它永远不会更新您的范围内的用户对象。

答案 2 :(得分:0)

为什么会这样?

$scope.user = userService;

此处userService对象直接分配给范围,因此将userService对象分配给范围变量后的所有更新都将反映到范围中。例如

var userService = {};
$scope.user = userService;
alert($scope.user.username);
angular.extend(userService, {"username":"User"});
alert($scope.user.username);

因此,在上面的示例$scope.user.username中,最后一个语句中的值为User

为什么这不起作用?

$scope.user = {
  username: userService.username,
  authenticated: userService.authenticated
};

此处的值从userService中提取并分配到范围,因此对userService的未来更改不会反映到范围中。这就是$scope.user.usernameundefined

的原因

创建jsfiddle来解释相同的

<强>解决方案

在我看来,您应初始化/重新初始化$scope.user successuserService次事件{/ 1}}。