在 ng-click 中更改 ng-include 中的模板

5

当用户在登录表单处进行了身份验证后,我尝试加载不同的模板。我可能已经找到了问题,我认为这是因为我没有在相同范围内工作。

我在作用域中有一个名为template的属性,当用户成功登录时我会更改它,但这种方法存在问题,因为如果我再次调用AccountCtrl,模板将被覆盖为登录模板:

var AccountCtrl = WorkerApp.controller('AccountCtrl', function ($scope, $location, AccountService) {

    $scope.template = 'Home/Template/login';

    $scope.Login = function () {
                    $scope.template = "Home/Template/register";
            };
        };
    }    
});

在我的index.html中,我有一些HTML代码超出了ng-view的范围:
    <div class="container">
    <div class="header">
        <div class="loginView">
            <div ng-include="template" ng-controller="AccountCtrl"></div>
        </div>
    </div>
</div>

我的登录模板
  <form name="login" ng-controller="AccountCtrl">
        <button class="btn btn-primary btn-sm" ng-click="Login()">Login</button>
    {{template}}
</form>

我对Angular并不是很熟悉,无法确定哪种方式是符合Angular的解决方法。在我的模板中,我可以移除ng-controller="AccountCtrl",但这样我就无法调用控制器中的登录函数(我已经测试过了)。


'AngularJS ng-include' 不会包含视图,除非在作用域中传递。 - Pedro Fillastre
2个回答

1

使用根作用域跟踪用户是否已通过身份验证,然后根据该布尔值隐藏/显示部分内容。

angular.module('myApp', []).run(function($rootScope) {
  $rootSCope.isAuthenticated = false;
});

var AccountCtrl = WorkerApp.controller('AccountCtrl', function ($scope, $location, AccountService) {
  $scope.Login = function () {
    $scope.$root.isAuthenticated = true;
  };
};

var AuthenticatedCtrl = function() {
  // Whatever you want to do once authenticated.
};

然后:

<div class="container" ng-show="isAuthenticated">
  <div class="header">
    <div class="loginView">
      <div ng-include="Home/Template/register" ng-controller="AuthenticatedCtrl"></div>
     </div>
  </div>
</div>

<form name="login" ng-controller="AccountCtrl"
  ng-hide="isAuthenticated"
  ng-include="Home/Template/login">
  <!-- The template should include a button that calls $scope.Login, obviously. -->
</form>

我稍微调整了一下,现在它可以工作了。我甚至没有想到使用ng-show和ng-hide,并将它们绑定到同一个属性上。 - Timsen
只是好奇。如果有人在浏览器中打开控制台并输入:$scope.$root.isAuthenticated = true;,会发生什么? - Ronen
@Ronen 在进行任何前端身份验证时,这总是一个真正的可能性,这就是为什么不应该向他们提供任何真正危险的东西。如果您想做正确的事情,应该从服务器传回某种身份验证令牌,该令牌将随任何后续的ajax请求一起发送以获取实际数据。 - Joe

1
您的代码现在存在问题,AccountCtrl将会被创建两次。因为您在页面上声明了两次(一次是模板加载到ng-include中)。这将导致template的默认值最初设置为login。所以我认为,您看到的不是template字段重置,而是一个新控制器设置默认值。
因此,您可以通过几种不同的方式来解决这个问题。
然而,我认为最好的方法是将选择模板的逻辑与注册或登录的逻辑分开。因此,您可能只需要几个不同的控制器。然后,顶层控制器将负责过渡ng-include的模板,仅此而已。
另一种方法是在ng-include内部引用顶层模板。从1.2版本开始,ng-include会创建一个子范围。因此,在这个解决方案中,您不需要在login模板中定义AccountCtrl。相反,您可以使用$scope.$parent.template来引用模板。

谢谢回答,你给了我一个重构代码的想法。 - Timsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接