Angular Noobie hier. Ich würde gerne wissen, wie man den Dom am besten ändert, wenn sich ein Wert im Bereich auf irgendeine Weise ändert. Ich habe gelesen, dass es nicht gut ist, die Dom-Manipulationslogik in den Controller zu integrieren, und das ist die Aufgabe von Anweisungen.

Hier ist ein Plunker

http://plnkr.co/edit/xWk5UBwifbCF2raVvw81?p=preview

Grundsätzlich möchte ich, dass die Zellen, deren Werte sich geändert haben, automatisch hervorgehoben werden, wenn sich die Daten durch Klicken auf die Schaltfläche Daten laden im Plunkr oben ändern. Ich kann es nicht dazu bringen, für mein Leben zu arbeiten.

Irgendeine Hilfe?

11
Jenos 21 Nov. 2013 im 12:31

3 Antworten

Beste Antwort

Ich denke, es wäre besser, einen konkreten Wert pro Textmarker zu beobachten, als die gesamte Sammlung zu betrachten. Z.B.:

<td highlighter="person.firstName">{{ person.firstName }}</td>

Auf diese Weise kann die highlighter - Direktive sehr einfach sein, wie:

app.directive('highlighter', ['$timeout', function($timeout) {
  return {
    restrict: 'A',
    scope: {
      model: '=highlighter'
    },
    link: function(scope, element) {
      scope.$watch('model', function (nv, ov) {
        if (nv !== ov) {
          // apply class
          element.addClass('highlight');

          // auto remove after some delay
          $timeout(function () {
            element.removeClass('highlight');
          }, 1000);
        }
      });
    }
  };
}]);

Damit dies funktioniert, müssen Sie jedoch angeben, dass sich die Daten tatsächlich geändert haben. Derzeit ist dies bei Winkelspuren people nach Objektidentität nicht der Fall. In dem Moment, in dem Sie es überschreiben, entfernt Angular alle zugehörigen Dom-Elemente. Verwenden Sie dazu:

ng-repeat="person in people track by $index"

Dadurch wird Angular angewiesen, den Index des Arrays als Identität zu behandeln.

Demo: http://jsbin.com/vutevifadi/1/

27
Yoshi 25 März 2015 im 15:26

Vielen Dank für die Antwort oben. Ich habe festgestellt, dass die Animation flackert, wenn sich der Wert häufig ändert und eine Zeitüberschreitung ausgelöst wird, während eine andere Animation bereits aktiv ist.

Ich habe dies behoben, indem ich das Zeitlimit zurückgesetzt habe, wenn das Zeitlimit bereits eingestellt ist.

Außerdem habe ich Code hinzugefügt, um zu überprüfen, ob der Wert zunimmt oder abnimmt, und verschiedene CSS-Klassen festgelegt.

app.directive('newvalue', ['$timeout', function($timeout) {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
        element.addClass('newvalue');
        scope.$watch(attrs.newvalue, function (nv, ov) {
        function settimeout() {
            attrs.timeout = $timeout(function () {
                element.removeClass('newvalue-up');
                element.removeClass('newvalue-down');
                attrs.timeout = null;
            }, 1000);
        }
        if (nv !== ov) {
            if(attrs.timeout) {
                //newvalue already set.. reset timeout
                $timeout.cancel(attrs.timeout);
                settimeout();
            } else {
                if(nv > ov) {
                    element.addClass('newvalue-up');
                } else {
                    element.addClass('newvalue-down');
                }
                settimeout();
            }
        }
      });
    }
  };
}]);
6
Soichi Hayashi 31 Mai 2014 im 03:18

Nach einigem Lesen bemerkte ich, dass es einige Zweifel an der Verwendung von $watch gibt, wenn man die Leistung berücksichtigt. Ich habe mit $observe eine andere Lösung gefunden.

Eine gute Lektüre zu $watch und $observe: https://stackoverflow.com/a/14907826/2901207

Javascript:

var app = angular.module('angularjs-starter', []);
app.directive('highlightOnChange', function() {
  return {
    link : function(scope, element, attrs) {
      attrs.$observe( 'highlightOnChange', function ( val ) {
        console.log("Highlighting", val);
        element.effect('highlight');
      });
    }
  };
});

app.controller('myController', function($scope, $timeout) {
  $scope.val = 1;
  $scope.updateVal = function() {
    $scope.val = $scope.val + 1;
  };
}); 

Html:

  <body ng-controller="myController">
    <div highlight-on-change="{{val}}">
      Total: {{ val }}
    </div>
    <button ng-click="updateVal()">Add to Total</button>
  </body>

Originalquelle: http://plnkr.co/edit/FFBhPIRuT0NA2DZhtoAD?p=preview aus diesem Beitrag: https://groups.google.com/d/ msg / angle / xZptsb-NYc4 / YH35m39Eo2wJ

Eine etwas komplexere Verwendung, die für mich perfekt funktioniert, da sie die spezifische Spalte hervorhebt, wenn ein Update kommt.

<table class="table table-hover">
        <tr>
            <th ng-repeat="col in fc.tableColumns"><!--fc is a controller-->
                {{col.displayName}}
            </th>
        </tr>
        <tr ng-repeat="item in fc.items track by item.id">
            <td highlight-on-change="{{value}}" ng-repeat="(key,value) in item">
               @*{{key}} =*@ {{value}}
            </td>
        </tr>
    </table>

Wie gesagt, aktualisiert die spezifische Spalte, während Sie dies irgendwo in der Steuerung tun.

items[index] = item;//item from server
3
Community 23 Mai 2017 im 11:54