AngularJS:在视图上多次使用相同的控制器 [英] AngularJS: Using the same controller multiple times on a view

查看:23
本文介绍了AngularJS:在视图上多次使用相同的控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在深入研究 Angularjs 并达到了让我的应用程序超越简单的待办事项列表阶段的程度.

我有一个场景,它必须是常见的,是有一个控制器需要在我的视图中的多个区域之间共享.

就我而言,我有一个 profileController,我想用它在每次加载时从服务器获取用户的个人资料.

当从 profileController 中调用 loadUserProfile 时,我看到它被称为 'n'-times(我在视图上引用控制器的次数),这很酷,所以我将 profileController 更改为简单地公开变量,例如 userProfile 和 isAuthenticated,它们仅引用我在 $rootScope 中设置的变量.这些变量设置在一个控制器中,该控制器在我的 <body data-ng-controller="baseController as vm"> 上声明的每页加载一次,但是这似乎不起作用,我我想知道我错过了什么.

所以它从 profileService 获取数据,但是在更新 $rootScope 变量时,它不会在我的视图中反映出来.

下面是我的 baseController:

(函数(){'使用严格';var controllerId = 'baseController';angular.module('app.controllers').controller(controllerId, ['$location', 'common', 'authClientSvc', 'profileService', '$rootScope', baseController]);函数 baseController($location, common, authClientSvc, profileService, $rootScope) {var getLogFn = common.logger.getLogFn;var log = getLogFn(controllerId);var vm = 这个;$rootScope.isAuthenticated = false;$rootScope.userProfile = {电子邮件: '',姓名: '',姓: ''};启用();功能激活(){var promises = [getUserProfile()];common.activateController([promises], controllerId).then(function () { log('Activated Secure View'); });}函数 getUserProfile() {profileService.getProfile('a@a.com').then(function (data) {设置超时(函数(){$rootScope.$apply(function () {$rootScope.userProfile = 数据;$rootScope.isAuthenticated = authClientSvc.isAuthenticated()})}, 1000);});}}})();

还有我的 profileController,我在这里公开了下面的 $rootScope 变量:

(函数(){'使用严格';var controllerId = 'profileController';angular.module('app').controller(controllerId, ['common', 'authClientSvc', 'profileService', '$rootScope', profileController]);功能 profileController(common, authClientSvc, profileService, $rootScope) {var getLogFn = common.logger.getLogFn;var log = getLogFn(controllerId);var vm = 这个;vm.logoutUrl = '/';vm.isAuthenticated = $rootScope.isAuthenticated;vm.profile = $rootScope.userProfile;启用();功能激活(){var 承诺 = [];common.activateController(promises, controllerId).then(function () { log('Activated Profile controller'); });}vm.logOut = 函数 () {authClientSvc.logout();}}})();

我不确定出了什么问题,因为在 Fiddler 中我可以清楚地看到返回的数据,并且当我调试它并在获取配置文件后将日志消息放入 baseController 时,它会返回正确的数据,但是对于某种原因它不适用于我的元素.下面是我如何在视图中使用它的示例:

我们将不胜感激,甚至可以提供有关如何以更好的方式实现这一目标的建议.

谢谢.

解决方案

根据 Angular 文档:

<块引用>

当控制器通过 ng-controller 指令附加到 DOM 时,Angular 将使用指定的控制器的构造函数实例化一个新的控制器对象.一个新的子作用域将作为 $scope 的可注入参数提供给 Controller 的构造函数.

含义:控制器在 ng-controller 指令附加到 DOM 时被实例化.如果您有两个 ng-controller,那么您将拥有两个独立的 ng-controller 实例.

<块引用>

不要使用控制器来:

  • 在控制器之间共享代码或状态 - 改用 Angular 服务.

I am delving into Angularjs and got to the point where I am taking my application beyond the simple todo list stages.

A scenario I have, which must be common, is to have one controller that needs to be shared across multiple areas on my view.

In my case I have a profileController which I want to use to get the profile of the user from the server on each load.

When calling the loadUserProfile from within the profileController I saw that it was called 'n'-times (for the number of times I referenced the controller on the view), which is cool, so I changed the profileController to simply expose variables such as userProfile and isAuthenticated which simply references variables that I set in the $rootScope. These variables are set in a controller that is loaded once per page declared on my <body data-ng-controller="baseController as vm">, however this does not seem to work, and I am wondering what I am missing.

So it get's the data from the profileService, but when updating the $rootScope variables, it does not reflect it on my view.

Below is my baseController:

(function () {
    'use strict';

    var controllerId = 'baseController';
    angular.module('app.controllers').controller(controllerId, ['$location', 'common', 'authClientSvc', 'profileService', '$rootScope', baseController]);

    function baseController($location, common, authClientSvc, profileService, $rootScope) {
        var getLogFn = common.logger.getLogFn;
        var log = getLogFn(controllerId);
        var vm = this;

        $rootScope.isAuthenticated = false;
        $rootScope.userProfile = {
            email: '',
            name: '',
            surname: ''
        };


        activate();

        function activate() {
            var promises = [getUserProfile()];
            common.activateController([promises], controllerId)
                .then(function () { log('Activated Secure View'); });
        }

        function getUserProfile() {
            profileService.getProfile('a@a.com').then(function (data) {
                setTimeout(function () {
                    $rootScope.$apply(function () {
                        $rootScope.userProfile = data;
                        $rootScope.isAuthenticated = authClientSvc.isAuthenticated()
                    })
                }, 1000);
            });
        }
    }
})();

And my profileController where I expose the $rootScope variables below:

(function () {
    'use strict';

    var controllerId = 'profileController';
    angular.module('app')
        .controller(controllerId, ['common', 'authClientSvc', 'profileService', '$rootScope', profileController]);

    function profileController(common, authClientSvc, profileService, $rootScope) {
        var getLogFn = common.logger.getLogFn;
        var log = getLogFn(controllerId);

        var vm = this;

        vm.logoutUrl = '/';

        vm.isAuthenticated = $rootScope.isAuthenticated;
        vm.profile = $rootScope.userProfile;

        activate();

        function activate() {
            var promises = [];
            common.activateController(promises, controllerId)
                .then(function () { log('Activated Profile controller'); });
        }

        vm.logOut = function () {
            authClientSvc.logout();
        }
    }
})();

I am not sure what is wrong, because in Fiddler I can clearly see the data coming back, and when I debug it and put log messages in the baseController after if gets the profile, it gets back the right data, but for some reason it is not working on my elements. Below is a sample of how I use it on the view:

<div class="login-info" data-ng-controller="profileController as vm">
    <span ng-switch="vm.isAuthenticated">
        <a ng-switch-when="true" href="javascript:void(0);" id="show-shortcut" data-action="toggleShortcut">
            <img src="/Content/img/avatars/male.png" alt="me" class="online" />
            <span data-localize="{{vm.profile.name}}.{{vm.profile.surname}}">
                {{vm.profile.name}}.{{vm.profile.surname}}
            </span>
            <i class="fa fa-angle-down"></i>
        </a>
        <span ng-switch-when="false">
            <img src="/Content/img/avatars/male.png" alt="guest" class="online" />
            <span data-localize="Guest.user">
                Guest User
            </span>
        </span>
    </span>
</div>

Any help would be greatly appreciated, or even suggestions on how to achieve this in a better way.

Thanks.

解决方案

According to Angular documentation:

When a Controller is attached to the DOM via the ng-controller directive, Angular will instantiate a new Controller object, using the specified Controller's constructor function. A new child scope will be available as an injectable parameter to the Controller's constructor function as $scope.

Meaning: Controllers are instantiated when the ng-controller directive is attached to the DOM. If you have two ng-controllers, then you will have two separate instances of ng-controller.

And

Do not use controllers to:

  • Share code or state across controllers — Use angular services instead.

这篇关于AngularJS:在视图上多次使用相同的控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆