web-dev-qa-db-fra.com

Actualisation de la directive angulaire lors du changement de paramètre

J'ai une directive angulaire qui est initialisée comme suit:

<conversation style="height:300px" type="convo" type-id="{{some_prop}}"></conversation>

J'aimerais qu'il soit suffisamment intelligent pour actualiser la directive lorsque $scope.some_prop change, car cela implique que le contenu affiché soit complètement différent.

Je l'ai testé en l'état et rien ne se passe, la fonction de liaison n'est même pas appelée lorsque $scope.some_prop change. Y a-t-il un moyen d'y arriver?

70
Luke Sapan

La fonction de liaison n'est appelée qu'une seule fois, elle ne ferait donc pas directement ce que vous attendiez. Vous devez utiliser un $watch angulaire pour regarder une variable de modèle. 

Cette montre doit être configurée dans la fonction de liaison.

Si vous utilisez un champ d'application isolé pour la directive, le champ d'application serait

scope :{typeId:'@' }

Dans votre fonction de lien, vous ajoutez une montre comme

link: function(scope, element, attrs) {
    scope.$watch("typeId",function(newValue,oldValue) {
        //This gets called when data changes.
    });
 }

Si vous n'utilisez pas de portée isolée, surveillez sur some_prop

91
Chandermani

Ce que vous essayez de faire est de surveiller la propriété d'attribut dans la directive. Vous pouvez regarder la propriété des changements d'attribut en utilisant $ observe () comme suit:

angular.module('myApp').directive('conversation', function() {
  return {
    restrict: 'E',
    replace: true,
    compile: function(tElement, attr) {
      attr.$observe('typeId', function(data) {
            console.log("Updated data ", data);
      }, true);

    }
  };
});

N'oubliez pas que j'ai utilisé la fonction 'compiler' dans la directive car vous n'avez pas indiqué si vous avez des modèles et si cela est sensible aux performances. 

Si vous avez des modèles, vous devez changer la fonction 'compile' en 'link' ou utiliser 'controller' et pour surveiller la propriété des modifications d'un modèle, utilisez $ watch () , et prenez les accolades angulaires {{}} de la propriété, exemple:

<conversation style="height:300px" type="convo" type-id="some_prop"></conversation>

Et dans la directive:

angular.module('myApp').directive('conversation', function() {
  return {
    scope: {
      typeId: '=',
    },
    link: function(scope, Elm, attr) {

      scope.$watch('typeId', function(newValue, oldValue) {
          if (newValue !== oldValue) {
            // You actions here
            console.log("I got the new value! ", newValue);
          }
      }, true);

    }
  };
});
36
j8io

J'espère que cela aidera à recharger/actualiser la directive sur la valeur de la portée parent 

<html>

        <head>
            <!-- version 1.4.5 -->
            <script src="angular.js"></script>
        </head>

        <body ng-app="app" ng-controller="Ctrl">

            <my-test reload-on="update"></my-test><br>
            <button ng-click="update = update+1;">update {{update}}</button>
        </body>
        <script>
            var app = angular.module('app', [])
            app.controller('Ctrl', function($scope) {

                $scope.update = 0;
            });
            app.directive('myTest', function() {
                return {
                    restrict: 'AE',
                    scope: {
                        reloadOn: '='
                    },
                    controller: function($scope) {
                        $scope.$watch('reloadOn', function(newVal, oldVal) {
                            //  all directive code here
                            console.log("Reloaded successfully......" + $scope.reloadOn);
                        });
                    },
                    template: '<span>  {{reloadOn}} </span>'
                }
            });
        </script>


   </html>
1
Abdul
angular.module('app').directive('conversation', function() {
    return {
        restrict: 'E',
        link: function ($scope, $Elm, $attr) {
            $scope.$watch("some_prop", function (newValue, oldValue) {
                  var typeId = $attr.type-id;
                  // Your logic.
            });
        }
    };
}
0
Gelio

Si vous êtes sous AngularJS 1.5.3 ou plus récent, vous devriez envisager de passer aux composants plutôt qu'aux directives . Ces fonctions ressemblent beaucoup aux directives mais avec quelques fonctionnalités supplémentaires très utiles, telles que $ onChanges (changesObj), le hook de cycle de vie, qui sera appelé à chaque mise à jour des liaisons unidirectionnelles. 

app.component('conversation ', {
    bindings: {
    type: '@',
    typeId: '='
    },
    controller: function() {
        this.$onChanges = function(changes) {
            // check if your specific property has changed
            // that because $onChanges is fired whenever each property is changed from you parent ctrl
            if(!!changes.typeId){
                refreshYourComponent();
            }
        };
    },
    templateUrl: 'conversation .html'
});

Voici les docs pour approfondir les composants.

0
voodoo_patch