it-swarm.com.de

Wie wird die AngularJS-Controller-Funktion beim Laden einer Seite ausgeführt?

Derzeit habe ich eine Angular.js-Seite, auf der gesucht und Ergebnisse angezeigt werden können. Der Benutzer klickt auf ein Suchergebnis und dann auf die Schaltfläche "Zurück". Ich möchte, dass die Suchergebnisse erneut angezeigt werden, kann jedoch nicht herausfinden, wie die auszuführende Suche ausgelöst wird. Hier ist das Detail:

  • Meine Angular.js-Seite ist eine Suchseite mit einem Suchfeld und einer Suchschaltfläche. Der Benutzer kann eine Abfrage manuell eingeben und eine Taste drücken, und eine Ajax-Abfrage wird ausgelöst und die Ergebnisse werden angezeigt. Ich aktualisiere die URL mit dem Suchbegriff. Das alles funktioniert gut.
  • Der Benutzer klickt auf ein Ergebnis der Suche und wird auf eine andere Seite weitergeleitet - das funktioniert auch.
  • Der Benutzer klickt auf die Schaltfläche "Zurück" und kehrt zur Seite "angular" zurück, und die richtige URL wird einschließlich des Suchbegriffs angezeigt. Alles funktioniert gut.
  • Ich habe den Suchfeldwert an den Suchbegriff in der URL gebunden, sodass er den erwarteten Suchbegriff enthält. Alles funktioniert gut.

Wie kann ich die Suchfunktion erneut ausführen, ohne dass der Benutzer den "Suchknopf" drücken muss? Wenn es jquery wäre, würde ich eine Funktion in der documentready-Funktion ausführen. Ich kann das Angular.js-Äquivalent nicht sehen.

354
Duke Dougal

Einerseits, wie @ Mark-Rajcok sagte, kann man mit einer privaten inneren Funktion davonkommen:

// 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();

Sie können sich auch die Direktive ng-init ansehen. Die Implementierung wird ungefähr so ​​aussehen wie:

// 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
};

Aber machen Sie sich darüber keine Sorgen, da Winkeldokumentation impliziert (seit v1.2) NICHT ng-init dafür verwendet. Es hängt jedoch von der Architektur Ihrer App ab.

Ich habe ng-init verwendet, als ich einen Wert aus dem Back-End an angular übergeben wollte.

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

Versuche dies?

$scope.$on('$viewContentLoaded', function() {
    //call it here
});
135

Ich könnte $viewContentLoaded nie zum Laufen bringen, und ng-init sollte eigentlich nur in einem ng-repeat (laut Dokumentation) verwendet werden, und auch das Aufrufen einer Funktion direkt in einem Controller kann dazu führen Fehler, wenn der Code auf einem Element basiert, das noch nicht definiert wurde.

Das mache ich und es funktioniert für mich:

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

Es sei denn, Sie verwenden ui-router. Dann ist es:

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

    // your code here

});
42
Carlos Trujillo

Dimitris/Marks Lösung hat bei mir nicht funktioniert, aber die Verwendung der Funktion $ timeout scheint gut zu funktionieren, um sicherzustellen, dass Ihr Code erst ausgeführt wird, nachdem das Markup gerendert wurde.

# Your controller, including $timeout

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

$timeout($scope.init)

Ich hoffe es hilft.

29
guico

Sie können dies tun, wenn Sie das viewContentLoaded-DOM-Objekt beobachten möchten, um es zu ändern, und dann etwas tun möchten. Die Verwendung von $ scope. $ on funktioniert ebenfalls, jedoch anders, insbesondere wenn Sie einen Seitenmodus für Ihr Routing verwenden.

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

Sie können das $ window-Objekt von angular verwenden:

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

Eine andere Alternative:

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

(via https://stackoverflow.com/a/30258904/148412 )

4
ANeves

Bei Verwendung von $ routeProvider können Sie .state und bootstrap Ihren Dienst auflösen. Dies bedeutet, dass Sie Controller und View erst laden werden, nachdem Sie Ihren Dienst aufgelöst haben:

ui-routen

 .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;
          }
        }
      })

Bedienung

function ourBootstrapService() {

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

Ich hatte das gleiche Problem und nur diese Lösung funktionierte für mich (sie führt eine Funktion aus, nachdem ein vollständiges DOM geladen wurde). Ich benutze dies, um nach dem Laden der Seite zum Anker zu scrollen:

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

                        // Your function that runs after all DOM is loaded

                    });
3
Ginko Balboa

Noch eine Alternative, wenn Sie einen Controller haben, der nur für diese Seite spezifisch ist:

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

Gefunden Dmitry Evseev Antwort sehr nützlich.

Fall 1: Nur AngularJs verwenden:
Um eine Methode beim Laden einer Seite auszuführen, können Sie ng-init in der Ansicht verwenden und die init-Methode im Controller deklarieren. Allerdings wird die Verwendung einer schwereren Funktion gemäß winklig) nicht empfohlen Docs on ng-init :

Diese Anweisung kann missbraucht werden, um Ihren Vorlagen unnötig viel Logik hinzuzufügen. Es gibt nur wenige geeignete Verwendungen von ngInit, z. B. für das Aliasing spezieller Eigenschaften von ngRepeat (siehe folgende Demo). und zum Einfügen von Daten über serverseitiges Scripting. Abgesehen von diesen wenigen Fällen sollten Sie Controller anstelle von ngInit verwenden, um Werte für einen Bereich zu initialisieren.

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

Warnung: Verwenden Sie diesen Controller nicht für eine andere Ansicht, die für eine andere Absicht bestimmt ist, da sonst die Suchmethode auch dort ausgeführt wird.

Fall 2: Verwenden von Ionic:
Der obige Code funktioniert, stellen Sie jedoch sicher, dass der Ansichtscache in route.js deaktiviert ist.

route.js

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

Hoffe das hilft

3
Kailas

Sie können die Suchergebnisse in einem allgemeinen Dienst speichern, der von überall verwendet werden kann und nicht gelöscht wird, wenn Sie zu einer anderen Seite navigieren. Anschließend können Sie die Suchergebnisse mit den gespeicherten Daten für den Klick auf die Schaltfläche "Zurück" festlegen

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

Für deinen Backbutton

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

rufen Sie initiale Methoden in der Funktion self initialize auf.

(function initController() {

    // do your initialize here

})();
0
Uditha Prasad