Aktualisierung der Angular-Direktive bei Parameteränderung

Lesezeit: 4 Minuten

Benutzer-Avatar
Lukas Sapan

Ich habe eine eckige Direktive, die wie folgt initialisiert wird:

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

Ich möchte, dass es klug genug ist, die Richtlinie wann zu aktualisieren $scope.some_prop Änderungen, da dies impliziert, dass es völlig andere Inhalte zeigen sollte.

Ich habe es so getestet, wie es ist, und es passiert nichts, die Verknüpfungsfunktion wird nicht einmal aufgerufen, wenn $scope.some_prop Änderungen. Gibt es eine Möglichkeit, dies zu erreichen?

Benutzer-Avatar
Chandermani

Die Link-Funktion wird nur einmal aufgerufen, daher würde sie nicht direkt das tun, was Sie erwarten. Sie müssen eckig verwenden $watch um eine Modellvariable zu beobachten.

Diese Uhr muss in der Link-Funktion eingerichtet werden.

Wenn Sie einen isolierten Geltungsbereich für Richtlinien verwenden, wäre der Geltungsbereich

scope :{typeId:'@' }

In deiner Linkfunktion fügst du dann gerne eine Uhr hinzu

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

Wenn Sie keinen isolierten Bereich verwenden, verwenden Sie watch on some_prop

  • Ich arbeite an einem ähnlichen Problem wie der OP. Die AngularJS-Dokumentation impliziert, dass using = in scope: erstellt eine bidirektionale Bindung, dh Änderungen im untergeordneten Bereich werden auf den übergeordneten Bereich übertragen und umgekehrt – ist dies nicht der Fall? Ich muss in der Lage sein, eine Direktive anzuweisen, sich selbst vom übergeordneten Controller zu aktualisieren.

    – Eno

    16. April 2015 um 22:22 Uhr


  • @Eno Hast du das herausgefunden? Verwirrt mich echt!

    – JMK

    5. Mai 2015 um 13:10 Uhr

  • @JMK Ich fand diese Artikel nützlich zu lesen: undefinednull.com/2014/02/11/… github.com/angular/angular.js/wiki/Understanding-Scopes

    – Eno

    8. Mai 2015 um 17:00 Uhr


  • Ist es schädlich, den Geltungsbereich von über 10000 Direktiven zu haben, die einen Geltungsbereich starten.

    – Léon Pelletier

    12. November 2015 um 21:18 Uhr


  • Ich habe festgestellt, dass die obige Lösung nicht funktioniert, wenn der Parameter ‘=’ verwendet, und ich untersuche sie.

    – Micky

    22. November 2017 um 11:19 Uhr

Benutzer-Avatar
j8io

Was Sie versuchen, ist, die Eigenschaft des Attributs in der Direktive zu überwachen. Sie können die Eigenschaft von Attributänderungen mit beobachten $beobachten() folgendermaßen:

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

    }
  };
});

Denken Sie daran, dass ich hier die Funktion „compile“ in der Anweisung verwendet habe, weil Sie nicht erwähnt haben, ob Sie Modelle haben und ob dies leistungsempfindlich ist.

Wenn Sie Modelle haben, müssen Sie die ‘kompilieren‘ Funktion zu ‘Verknüpfung‘ oder verwenden ‘Regler‘ und um die Eigenschaft eines Modells zu überwachen, sollten Sie verwenden $watch()und nehmen Sie die eckigen {{}} Klammern aus der Eigenschaft, Beispiel:

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

Und in der Richtlinie:

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

    }
  };
});

Ich hoffe, dies hilft beim Neuladen/Aktualisieren der Anweisung zum Wert aus dem übergeordneten Bereich

<html>

        <head>
            <!-- version 1.4.5 -->
            <script src="https://stackoverflow.com/questions/20856824/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>

Benutzer-Avatar
voodoo_patch

Wenn Sie unter AngularJS 1.5.3 oder neuer arbeiten, sollten Sie erwägen, zu Komponenten statt zu Direktiven zu wechseln. Diese funktionieren sehr ähnlich wie Direktiven, aber mit einigen sehr nützlichen zusätzlichen Funktionen, wie z. B. $onChanges(changesObj), einem der Lebenszyklus-Hooks, der aufgerufen wird, wenn One-Way-Bindings aktualisiert werden.

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

Hier ist die Dokumente zum Vertiefen in Bauteile.

1112220cookie-checkAktualisierung der Angular-Direktive bei Parameteränderung

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy