web-dev-qa-db-fra.com

Comment appliquer jquery après le chargement du modèle partiel AngularJS

J'ai un site Web simple qui implémente jQuery afin de créer un slider avec des images dans la bannière supérieure Index.html.

Maintenant, je veux utiliser AngularJS donc je divise le code HTML en partiels séparés.

  1. Entête
  2. Bas de page
  3. Bannière Supérieure

Si je lance Index.html dans la version d'origine (sans appliquer les motifs AngularJS), le curseur fonctionne parfaitement. 

Lors de l'application de modèles AngularJS, j'ai déplacé le code HTML de la bannière supérieure vers un code HTML partiel, puis appliqué ng-view au div où se trouvait à l'origine la bannière supérieure.

var app = angular.module('website', ['ngRoute']);
app.config(function($routeProvider) {
    $routeProvider.
    when('/about',{templateUrl:'app/partials/about.html'}).
    when('/contact',{templateUrl:'app/partials/contact.html'}).
    otherwise({redirectTo:'/home',templateUrl:'app/partials/home.html'})
});

Lorsque j'actualise la page, le curseur ne fonctionne pas, est rendu au format HTML simple, sans aucun effet jQuery, est vraiment un gâchis. 

Ce partials a quelques plugins jQuery qui s'active habituellement par document.ready. Mais cet événement ne se déclenche pas lorsque la charge angulaire est partielle dans ng-view. Comment puis-je appeler cet événement pour initialiser les plugins jQuery? 

Un indice comment résoudre ce problème?

Appréciez toute aide.

19
VAAA

Lorsque vous spécifiez vos itinéraires, vous pouvez également spécifier un contrôleur, afin que vos itinéraires ressemblent à ceci:

var app = angular.module('website', ['ngRoute']);
app.config(function($routeProvider) {
    $routeProvider.
        when('/about',{templateUrl:'app/partials/about.html', controller: 'aboutCtrl'}).
        when('/contact',{templateUrl:'app/partials/contact.html', controller: 'contactCtrl'}).
        otherwise({redirectTo:'/home',templateUrl:'app/partials/home.html', controller: 'homeCtrl'})
    });

Maintenant, vous pouvez définir dans chaque contrôleur ce que vous voulez faire, au niveau des requêtes, dans le cadre d’une fonction, comme ceci:

angular.module('website').controller('aboutCtrl', ['$scope', function ($scope) {

   $scope.load = function() {
       // do your $() stuff here
   };

   //don't forget to call the load function
   $scope.load();
}]);

Avoir un sens?

20
Aaron

Les autres réponses fournies fonctionneront, mais elles sont liées aux contrôleurs et ne sont donc pas aussi évolutives et réutilisables.

Pour le faire de la manière "angulaire" réelle, comme mentionné dans les commentaires, vous devriez utiliser une directive. L'avantage de ceci est que vous pouvez créer plusieurs instances avec le même code et que vous pouvez transmettre des attributs à la logique de directive pour personnaliser la directive. Voici un exemple d'utilisation de ce plugin à l'aide du plugin bxSlider :

JS:

app.directive('slider',  ['$rootScope', function($rootScope) {
return {
    restrict: 'EA',
    templateUrl: '/path/to/template',
    link: function(scope, iElement, attrs) {
        //attrs references any attributes on the directive element in html

        //iElement is the actual DOM element of the directive,
        //so you can bind to it with jQuery
        $(iElement).bxSlider({
            mode: 'fade',
            captions: true
        });

        //OR you could use that to find the element inside that needs the plugin
        $(iElement).find('.bx-wrapper').bxSlider({
            mode: 'fade',
            captions: true
        });

       }
    };
}]);

HTML:

<div slider some-attibute="some-attribute"></div>

Et dans votre modèle de directive, vous pouvez avoir l’encapsuleur et les diapositives, que vous pouvez créer dynamiquement à l’aide de ng-repeat lié aux données de portée. 

Je vous recommande de lire ceci excellent article de Dan Wahlin sur la création de directives personnalisées et sur la manière de les exploiter au mieux.

10
Sean Thompson

J'ai eu le même problème, je chargeais quelques liens de navigation dans un ng-include et j'ai un fichier script appelé sur mon index.html avec des instructions jquery pour rendre les liens actifs et je ne vois pas le contenu inclus.

J'ai essayé toutes les solutions ci-dessus et pour certaines raisons, aucune d'entre elles n'a fonctionné pour moi. Lorsque le contenu n'est pas inclus (directement dans l'index.html), jquery démarre correctement mais une fois inclus, il a cessé de reconnaître mes éléments.

J'ai donc simplement intégré mes instructions dans une fonction setTimeout () et cela a fonctionné! Peut-être que ça va marcher pour vous aussi?

setTimeout(function() {
    $("nav ul li").click(function() {
        $("nav ul li").removeClass('active');
        $(this).addClass('active');
    });
});

D'une manière ou d'une autre, setTimeout () parvient à charger le script APRES que angular soit terminé, le chargement du contenu inclus.

Bon codage à tous!

1
Maranaho

Une directive est certainement une bonne option, mais vous pouvez également ajouter un contrôleur à tout partiel, qui effectuera toutes les tâches (également avec jQuery si vous le souhaitez) après le chargement du partiel: 

Exemple: partials/menu.html

<div ng-controller="partialMenuCtrl">
   ...
</div>
0
Gerfried

Je sais que c'est un vieux fil de discussion, mais pour compléter, vous pouvez utiliser le code JQuery suivant. C'est ce qu'on appelle la délégation d'événement. 

$("#anyDivOrDocument").on('click', '#targetDiv', function(event) {
   event.preventDefault();
   alert( 'working' ); 
});
0
user3932437

J'ai acheté un modèle html5 et essayé de l'intégrer à mon application Web angularJS. J'ai rencontré le même problème. Je l'ai résolu en utilisant:

Mettez le code ci-dessous à l'endroit où vous mettez votre code <script src="vendor/61345/js/script.js"></script>.

<script>
   document.write('<script src="vendor/61345/js/script.js"><\/script>');
</script>
0
USAZ

J'ai eu le même problème, je courais Jquery slick slider en simple page html, il fonctionnait bien. Comment cela fonctionne fondamentalement en incluant le fichier slick.min.js sous le fichier jquery.min.js, puis dans les balises de script, vous devez initialiser le plugin avec des options telles que p. Ex. 

$('.items').slick({
   infinite: true,
   slidesToShow: 3,
   slidesToScroll: 3
});

revenons maintenant à la question, lorsque j’ai ajouté Angular JS à ma page et fait des partiels de la page, puis je suis retourné dans le navigateur pour vérifier si la page fonctionnait bien ou non, la page fonctionnait bien sauf le curseur. Ensuite, j'ai essayé de déplacer ces initialisations de slick.min.js et de plugins vers les partiels, et cela a fonctionné :)

Comment cela a fonctionné? Je ne connais pas la raison, puisque je suis nouveau sur Angular mais cela a fonctionné et je me demande toujours la raison.

0
Usman Khan