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

316

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

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

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

  • 0
    вы используете $routepProvider ? Используйте его для подключения к службе в вашем приложении, которая предоставляет данные для результатов поиска. Не думайте, что в document.ready Уже такие термины, как с jQuery. Трудно помочь, не видя, как у вас есть поиск в настоящее время
Теги:
onload

13 ответов

406
Лучший ответ

С одной стороны, как @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
};

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

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

<div data-ng-controller="myCtrl" data-ng-init="init('%some_backend_value%')"></div>
  • 6
    @Duke, вы не можете просто поместить содержимое функции init () внизу вашего контроллера? Т.е. зачем вам использовать ng-init и иметь функцию init ()? Когда пользователь нажимает кнопку «Назад», я предполагаю, что вы переключаете представления, поэтому новый контроллер myCtrl создается и выполняется.
  • 23
    В то время как это решение работает, я понизил голосование, потому что документация ng-init советует против этого. В частности: «Единственное подходящее использование ngInit для наложения псевдонимов специальных свойств ngRepeat, как видно из демонстрации ниже. Помимо этого случая, вы должны использовать контроллеры, а не ngInit для инициализации значений в области».
Показать ещё 7 комментариев
121

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

$scope.$on('$viewContentLoaded', function() {
    //call it here
});
  • 5
    Спасибо за ответ, но ответ Дмитрия точно соответствовал тому, что я ищу. Дальнейшие исследования, похоже, рекомендуют против $ viewContentLoaded
  • 7
    Варианты использования просто разные. Я все время использую метод Марка.
Показать ещё 3 комментария
57

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

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

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

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

$scope.$on('$stateChangeSuccess', function () {
  // do something
});
  • 1
    Ты потрясающий, мой друг.
  • 0
    Именно то, что мне было нужно. Я буквально искал это два дня!
Показать ещё 2 комментария
42
angular.element(document).ready(function () {

    // your code here

});
  • 4
    Должен быть принятый ответ, это более безопасный способ сделать это
  • 0
    Это хорошо, если мы не работаем с $scope и вместо этого работаем с this .
Показать ещё 3 комментария
29

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

# Your controller, including $timeout

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

$timeout($scope.init)

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

  • 3
    В заключение. Это единственный, который работал на меня. Благодарю.
  • 0
    Это работает. Также не забудьте очистить тайм-аут с помощью $ timeout.cancel (timer), где у вас есть var timer = $ timeout ($ scope.init, миллисекунды); как только ваша инициализация будет завершена. Кроме того, я не думаю, что $ scope должен иметь значение 'var' в вашем коде выше
Показать ещё 1 комментарий
24

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

 $scope.$watch('$viewContentLoaded', function(){
    // do something
 });
  • 7
    В частности, если вы используете $ rootScope. $ Watch вместо $ rootScope. $ On, он не сработает при изменении маршрута, поэтому вы можете использовать логику, специфичную для начальной загрузки страницы.
15

Вы можете использовать angular $window object:

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

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

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

(через https://stackoverflow.com/questions/21715256/angularjs-event-to-call-after-content-is-loaded)

3

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

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

                        // Your function that runs after all DOM is loaded

                    });
3

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

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

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

HTML:

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

Контроллер:

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'
  })

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

  • 1
    У этого был только один вверх и был в самом низу, рад, что я прошел весь путь вниз, cache: false сделал это для меня - спасибо!
3

При использовании $routeProvider вы можете разрешить в .state и загружать свою службу. Это означает, что вы собираетесь загрузить 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
 }
}
2

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

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

For your backbutton

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню