AngularJS绑定,多个控制器通过一个服务,部分页面由php渲染

Posted

技术标签:

【中文标题】AngularJS绑定,多个控制器通过一个服务,部分页面由php渲染【英文标题】:AngularJS Binding, multiple controllers through a service, part of page rendered from php 【发布时间】:2013-08-14 02:07:21 【问题描述】:

我知道这很长,但在更复杂的情况下我正在做的事情似乎是导致问题的具体原因。我尝试的所有简单示例都可以正常工作。

我有一个使用 angularjs 和 laravel 4 的应用程序设置。

首页通过laravel路由渲染:

Route::get('/', function() 
    return View::make('app');
);

app.php 返回具有以下结构的网站骨架:

<!doctype html>
<html lang="en" ng-app="app">
<head>


  <script src="/js/angular.js"></script>
  <script src="/js/angular-sanitize.js"></script>
  <script src="/js/angular-ui-router.js"></script>
  <script src="/js/app.js"></script>

</head>
<body>

    <div class="navbar navbar-inverse navbar-fixed-top" ng-controller="NavController">
        <div class="navbar-inner">
            <div class="container-fluid">
                    <button class="button pull-right" ng-click="logout()">Logout</button>
                    <p class="navbar-text pull-right" >
                        Logged in as <a href="#" class="navbar-link"> currentUser.email  id is :  currentUser.userId </a>
                    </p>
                </div>
            </div>
        </div>
    </div>

  <div class="row-fluid offset05">
      <div id="view" ng-view></div>
    </div>
  </div>

</body>
</html>

app.js 的基础知识:

var app = angular.module("app", ['ngSanitize','ui.state','ui.bootstrap']);

用户最初被路由到登录模板,此时 LoginController 更新驻留在 UserService 中的用户信息。

app.controller("LoginController", function($scope,$rootScope, $location, AuthenticationService, UserService) 

    $scope.credentials =  email: "", password: "" ;

  $scope.login = function() 
    AuthenticationService.login($scope.credentials).success(function() 
      $location.path('/home');
    );
  ;
);

Authentication Service 适当地更新 UserService 变量:

app.factory("AuthenticationService", function($rootScope, $http, $sanitize, SessionService, FlashService, CSRF_TOKEN, UserService) 

  return 
    login: function(credentials) 
      var login = $http.post("/auth/login", sanitizeCredentials(credentials));
      login.success(function(data)

           UserService.currentUser = data.user;

    );

      return login;
    
);

NavController(上面看到的导航栏控制器)将其范围绑定到 UserService.currentUser。

app.controller("NavController",function($scope, UserService, AuthenticationService,$location)

    $scope.currentUser = UserService.getCurrentUser();

);

UserService的相关部分:

app.factory("UserService", function($http)

var _currentUser = 

return
    currentUser: _currentUser,

    getCurrentUser: function() 
        return _currentUser;

    ;

);

当用户登录时,他们的用户电子邮件和用户 ID 应该出现在导航栏中。

如果我创建一个严格使用 javascript/html 的示例,则绑定没有问题。

使用上面提到的机制/结构,导航栏在重新加载整个页面之前不会响应 UserService 当前用户变量的变化。

用户登录后,我可以验证 UserController 和 UserService 是否都适当地更新了 currentUser。尽管如此,除非我重新加载整个页面,否则 NavController 不会反映更新的用户。

我认为这是因为 NavController 现在正在使用更新的信息重新运行,但为什么正常绑定不起作用?

我想这与导航栏是通过 php 加载的事实有关。

我的问题是我该怎么做: a) 使通过服务的绑定正常工作 要么 b) 必要时重新加载 NavController(登录/注销后)

【问题讨论】:

似乎应该有一个 $scope.$apply();登录控制器中的某个位置,以便在填充模型时消化并应用更改。 【参考方案1】:

有几种方法可以解决这个问题。

    您可以将您的 $scope 绑定到服务本身,在这种情况下,对该模型的任何更改都将被自动获取 您可以使用$watch 观察服务的变化

在此示例中,您可以看到两种技术:(http://plnkr.co/edit/bhBXMr?p=preview):

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

app.controller('MainCtrl', function($scope, AuthenticationService, UserService) 
  $scope.user = UserService;
  $scope.login = function()
    AuthenticationService.login();
  
  // watch the service for changes to currentUser
  $scope.$watch(function()
    return UserService.currentUser;
  , function(currentUser)
    $scope.currentUser = currentUser;
  , true);
);

app.service('AuthenticationService', function($http, UserService)
  return 
    login: function()
      $http.get('data.json').success(function(data)
        UserService.currentUser = data;
      );
    
  ;
);

app.service('UserService', function($rootScope)
  return 
    currentUser: null
  ;
);

HTML 标记:

<body ng-controller="MainCtrl">
  <button ng-click="login()">Login</button>
  <div>Current User: user.currentUser</div>
  <!-- from the watch -->
  <div>Current User: currentUser</div>
</body>

【讨论】:

以上是关于AngularJS绑定,多个控制器通过一个服务,部分页面由php渲染的主要内容,如果未能解决你的问题,请参考以下文章

AngularJs 中的两种方式数据绑定不使用异步回调

AngularJs 学习笔记依赖注入

在 AngularJS 服务中处理数据绑定

AngularJS路由

第二章:2.1 AngularJS 中的数据绑定

angularJS 1.5 嵌套组件