AngularJS — не удалось инициировать HTTP-вызов с контроллера

#angularjs #angular-controller

#angularjs #angular-контроллер

Вопрос:

Я создаю веб-сайт с использованием AngularJS и PHP. На веб-сайте есть много страниц, таких как Главная, О нас и т. Д.

Итак, я создал общий заголовок для веб-сайта, который я включил в свой HTML-вид следующим образом:

 <!DOCTYPE html>
<html ng-app="myApp">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Demo</title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
        <script src="angular.min.js"></script>
        <script src="angular-route.min.js"></script>
        <script src="commonController.js"></script>
        <script src="homeController.js"></script>
        <script src="loginController.js"></script>

        <script src="app.js"></script>

    </head>
    <body>
        <div class="header" ng-controller="CommonController"
             ng-include="'header.html'"></div>
        <div class="main" ng-view></div>
    </body>
</html>
  

и страница header ( header.html ) выглядит следующим образом:

 <nav class="navbar-inverse navbar-fixed-top" role="navigation">
    <a  href="#/home">Home</a>
    <a  href="#/notifications" >{{vm.commonId}}</a>
</nav>
  

и контроллер заголовка имеет http-вызов, который извлекает идентификатор пользователя, и я пытаюсь показать этот идентификатор в качестве метки для одной из ссылок, упомянутых выше ( commonController.js )

 (function() {

    angular
        .module('myApp.common', ['ngRoute'])

        .factory('myCommonService', function($http) {
            var baseUrl = 'api/';
            return {
                getBasicUserInfo:function() {
                    return $http.get(baseUrl   'getBasicUserInformation');
                }
            };
        })

        .controller('CommonController', function($scope, $routeParams, myCommonService) {
            var vm = this;      
            myCommonService.getBasicUserInfo().success(function(data) {
                vm.commonId = data.id;
            }); 
        });
})();
  

Но когда я просматриваю страницы, заголовок остается неизменным. Итак, я не могу инициировать этот http-вызов. На моем веб-сайте много страниц.

Можно ли это сделать? Я в значительной степени новичок в этой платформе.

Route ( app.js )

 (function() {

    angular.module('myApp', [
        'ngRoute',
        'myApp.login',
        'myApp.home',
        'myApp.common'
    ])
    .config(['$routeProvider', function($routeProvider) {
        $routeProvider
        .when('/login', {
            controller: 'LoginController',
            templateUrl: 'loginView.html',      
            controllerAs: 'vm'
        })
        .when('/home', {
            controller: 'HomeController',
            templateUrl: 'homeView.html',       
            controllerAs: 'vm'          
        })
        .otherwise({
            redirectTo: '/login'
        });
    }]);
})();
  

P.S: Я исключил другие страницы, чтобы уменьшить сложность и упростить понимание моего запроса.

Спасибо!

Комментарии:

1. Я использую ui-router which, который предлагает гораздо больше возможностей, чем routeProvider , и ваша проблема может быть легко решена. Это не решение для вас, но я подумал, что это может вам помочь.

2. Что вы делаете (function() {})() в своих файлах?

3. Новое в этом. Это неправильно? @Chrillewoodz

4. @SajeevC если бы вы вводили какие-либо переменные или функции в область IIFE , это стоило бы сделать, но в нынешнем виде они избыточны; все, что вы делаете, связано с глобальной angular переменной

5. Что сказал Фил.

Ответ №1:

Мне кажется, все, чего не хватает, — это сообщить шаблону псевдоним области действия для контроллера

 <div class="header" ng-controller="CommonController as common"
     ng-include="'header.html'"></div>
  

и в header.html

 <a href="#/notifications">{{common.commonId}}</a>
  

Обратите внимание, что я использовал common вместо vm того, чтобы использовать некоторые из ваших маршрутов vm , и лучше избегать конфликтов.


Если вы хотите инициировать обновление навигации по странице (т.Е. Изменение маршрута), Измените свой CommonController на этот

 .controller('CommonController', function($scope, myCommonService) {
    var ctrl = this;
    var update = function() {
        myCommonService.getBasicUserInfo().then(function(res) {
            ctrl.commonId = res.data.id;
        });
    };
    update();

    $scope.$on('$routeChangeSuccess', update);
});
  

Комментарии:

1. yeah.it показывает значение, но http-вызов getBasicUserInfo() инициируется только в первый раз (когда я загружаю веб-сайт). После этого, когда я перемещаюсь между страницами, он не вызывается. Подумайте, значение переменной изменяется (например, количество уведомлений или что-то в этом роде), поэтому я должен проверять этот вызов каждый раз @Phil

2. итак, когда приходит новое уведомление, значение переменной обновляется. Итак, я должен проверять этот вызов на каждой странице… чего я не могу сделать, поскольку заголовок остается неизменным для всей страницы. @Phil

3. @SajeevC что должно быть триггером для обновления уведомления? Вы можете опрашивать автоматически, используя $interval или обновлять вручную с учетом определенных событий. Каким он должен быть?

4. @SajeevC Я обновил свой ответ, включив пример последнего. Если вы хотите использовать $interval вместо этого, дайте мне знать.

Ответ №2:

Вы должны быть в состоянии сделать это:

 .when('/login', {
        controller: 'LoginController',
        templateUrl: 'loginView.html', 
        resolve: function(){ //your code here }
        controllerAs: 'vm'
    })
  

вместо того, чтобы получать его от контроллера

Ответ №3:

Я думаю, что ваша проблема может заключаться в том, что include не может прочитать контроллер, поэтому вместо этого попробуйте это:

 <nav class="navbar-inverse navbar-fixed-top" role="navigation" ng-controller="CommonController as vm">
  <a  href="#/home">Home</a>
  <a  href="#/notifications" >{{vm.commonId}}</a>
</nav>
  

Обратите внимание, что вам также не хватает controllerAs синтаксиса, поэтому я добавил это.

И удалить ng-controller отсюда:

 <div class="header" ng-include="'header.html'"></div>
  

Комментарии:

1. ng-include компилирует шаблон с текущей областью, поэтому проблема определенно не связана с вашим первым пунктом

2. @Phil Не уверен в этом, потому что у меня были проблемы с этим раньше. Я посмотрю, смогу ли я откопать свой старый вопрос об этом.