it-roy-ru.com

Как выполнить функцию контроллера AngularJS при загрузке страницы?

В настоящее время у меня есть страница Angular.js, которая позволяет искать и отображать результаты. Пользователь нажимает на результат поиска, а затем нажимает кнопку назад. Я хочу, чтобы результаты поиска снова отображались, но я не могу понять, как запустить поиск. Вот деталь:

  • Моя страница Angular.js - это страница поиска с полем поиска и кнопкой поиска. Пользователь может вручную ввести запрос и нажать кнопку, и запрос ajax запускается, и результаты отображаются. Я обновляю URL поисковым запросом. Это все работает отлично.
  • Пользователь нажимает на результат поиска и попадает на другую страницу - это тоже хорошо работает.
  • Пользователь нажимает кнопку "Назад" и возвращается на мою страницу поиска angular, и отображается правильный URL-адрес, включая условие поиска. Все работает отлично.
  • Я связал значение поля поиска с поисковым термином в URL, поэтому он содержит ожидаемый поисковый термин. Все работает отлично.

Как заставить функцию поиска снова выполняться без необходимости нажимать кнопку "Поиск"? Если бы это был jquery, я бы выполнил функцию в функции documentready. Я не вижу аналога Angular.js.

350
Duke Dougal

С одной стороны, как сказал @ Mark-Rajcok, вы можете просто уйти с частной внутренней функцией:

// at the bottom of your controller
var init = function () {
   // check if there is query in url
   // and fire search in case its value is not empty
};
// and fire it after definition
init();

Также вы можете взглянуть на директиву ng-init . Реализация будет очень похожа на:

// register controller in html
<div data-ng-controller="myCtrl" data-ng-init="init()"></div>

// in controller
$scope.init = function () {
    // check if there is query in url
    // and fire search in case its value is not empty
};

Но позаботьтесь об этом как угловая документация подразумевает (начиная с v1.2) чтобы НЕ использовать ng-init для этого. Однако, это зависит от архитектуры вашего приложения.

Я использовал ng-init, когда хотел передать значение из серверной части в приложение angular:

<div data-ng-controller="myCtrl" data-ng-init="init('%some_backend_value%')"></div>
419
Dmitry Evseev

Попробуй это?

$scope.$on('$viewContentLoaded', function() {
    //call it here
});
133
holographic-principle

Я никогда не мог заставить $viewContentLoaded работать на меня, и ng-init действительно должен использоваться только в ng-repeat (согласно документации), а также вызов функции непосредственно в контроллере может вызвать ошибки, если код использует элемент, который не имеет были определены еще.

Это то, что я делаю, и это работает для меня:

$scope.$on('$routeChangeSuccess', function () {
  // do something
});

Если вы не используете ui-router. Тогда это:

$scope.$on('$stateChangeSuccess', function () {
  // do something
});
59
adam0101
angular.element(document).ready(function () {

    // your code here

});
42
Carlos Trujillo

Решение Димитрия/Марка у меня не сработало, но использование функции $ timeout , кажется, работает хорошо, чтобы гарантировать, что ваш код запускается только после визуализации разметки.

# Your controller, including $timeout

var $scope.init = function(){
 //your code
}

$timeout($scope.init)

Надеюсь, поможет.

29
guico

Вы можете сделать это, если хотите посмотреть, как изменяется объект DOM viewContentLoaded, а затем что-то сделать. Использование $ scope. $ on тоже работает, но по-разному, особенно если в маршрутизации используется одностраничный режим.

 $scope.$watch('$viewContentLoaded', function(){
    // do something
 });
26
CodeOverRide

Вы можете использовать угловой объект $ window:

$window.onload = function(e) {
  //your magic here
}
19
mcgraw

Другая альтернатива:

var myInit = function () {
    //...
};
angular.element(document).ready(myInit);

(через https://stackoverflow.com/a/30258904/148412 )

4
ANeves

При использовании $ routeProvider вы можете разрешить в .state и bootstrap свой сервис. Это означает, что вы собираетесь загрузить Controller и View только после разрешения вашей службы:

uI-маршруты

 .state('nn', {
        url: "/nn",
        templateUrl: "views/home/n.html",
        controller: 'nnCtrl',
        resolve: {
          initialised: function (ourBootstrapService, $q) {

            var deferred = $q.defer();

            ourBootstrapService.init().then(function(initialised) {
              deferred.resolve(initialised);
            });
            return deferred.promise;
          }
        }
      })

Обслуживание

function ourBootstrapService() {

 function init(){ 
    // this is what we need
 }
}
3
Leo Lanese

У меня была та же проблема, и у меня работало только это решение (оно запускает функцию после полной загрузки DOM). Я использую это для прокрутки на якорь после загрузки страницы:

angular.element(window.document.body).ready(function () {

                        // Your function that runs after all DOM is loaded

                    });
3
Ginko Balboa

Еще одна альтернатива, если у вас есть контроллер, специфичный для этой страницы:

(function(){
    //code to run
}());
3
Chipe

Нашел Дмитрий Евсеев, ответ довольно полезный.

Случай 1: Использование только angularJs:
Чтобы выполнить метод при загрузке страницы, вы можете использовать ng-init в представлении и объявить метод init в контроллере, сказав, что использование более тяжелой функции не рекомендуется, согласно angular Docs на ng- INIT :

Эта директива может быть использована для добавления ненужного количества логики в ваши шаблоны. Существует только несколько подходящих вариантов использования ngInit, например, для псевдонимов специальных свойств ngRepeat, как показано в демонстрации ниже; и для ввода данных с помощью сценариев на стороне сервера. Помимо этих нескольких случаев, вы должны использовать контроллеры вместо ngInit для инициализации значений в области.

HTML:

<div ng-controller="searchController()">
    <!-- renaming view code here, including the search box and the buttons -->
</div>

Controller:

app.controller('SearchCtrl', function(){

    var doSearch = function(keyword){
        //Search code here
    }

    doSearch($routeParams.searchKeyword);
})

Предупреждение: Не используйте этот контроллер для другого представления, предназначенного для другого намерения, так как это также приведет к выполнению там метода поиска.

Случай 2: Использование Ionic:
Приведенный выше код будет работать, просто убедитесь, что кеш представления отключен в route.js как:

route.js

.state('app', {
    url           : '/search',
    cache         : false, //disable caching of the view here
    templateUrl   : 'templates/search.html'   ,
    controller    : 'SearchCtrl'
  })

Надеюсь это поможет

3
Kailas

Вы можете сохранить результаты поиска в общем сервисе, который можно использовать из любого места и который не удаляется при переходе на другую страницу, а затем вы можете установить результаты поиска с сохраненными данными для нажатия кнопки "Назад".

function search(searchTerm) {
    // retrieve the data here;
    RetrievedData = CallService();
    CommonFunctionalityService.saveSerachResults(RetrievedData);
} 

Для вашей кнопки

function Backbutton() {
    RetrievedData = CommonFunctionalityService.retrieveResults();
}
2
Heshan

вызовите начальные методы внутри функции собственной инициализации.

(function initController() {

    // do your initialize here

})();
0
Uditha Prasad