2016-03-31 7 views
0

Ich arbeite an einem Projekt, in dem der Client in der Lage sein muss, jede Zeichenfolge, die wir in der Anwendung verwendet haben, zu ändern. Dieser Bedarf ist ähnlich wie bei i18n, außer dass wir, das Entwicklerteam, und die Menge der Zeichenfolgen, die der Client nach seinen Änderungen erhalten kann, in der gleichen Sprache sind.AngularJS: Auslösen der Auswertung von Bindungen, die einen Filter enthalten

Ich habe daher einen Filter implementiert, so dass Zeichenfolgen in HTML-Ansichten als Angular-Ausdruck wie {{'one.code.on.view1' | label }} geschrieben werden. Der Filter stützt sich auf einen Dienst, der "sozusagen den gesamten Etikettensatz im Speicher hält".

Ich habe eine einfache Benutzeroberfläche entwickelt, mit der Benutzer Textbeschriftungen ändern können: Alle Beschriftungen werden in einem angular-ui-Raster angezeigt. Jede Zeile enthält den (nicht änderbaren) Code und das (änderbare) Label. Mit der Inline-Bearbeitungsfunktion des Rasters speichere ich das geänderte Etikett in der Datenbank. So weit, ist es gut.

Mein Problem ist, dass ich beim Speichern des modifizierten Labels in der Datenbank auch den Eintrag dieses Labels im Service "hold Labels" aktualisiert, aber leider, falls das geänderte Label auf dem Bildschirm angezeigt wurde, ist der alte Wert isn nicht aktualisiert.

Meine Frage ist: Wie kann ich eine Auswertung von Bindungen auf der Ansicht auslösen? Ich habe jedes $ Timeout oder $ Apply-Trick verwendet, das ich kannte, aber ohne Erfolg, was nicht sehr überraschend ist, da der gesamte Code in Angular-Kontexten abläuft.

Hier ist der Code des Filters und Service: (der Klarheit halber ist "libellé" das französische Wort für "Label", obwohl wir manchmal "Label" falsch verwenden, und "Scoop" ist der Name von das Projekt, damit seine Verwendung als Präfix)

function scoopLabelSceFn($resource, $rootScope, $timeout) { 
    var rest = $resource('admin/libelle/list', {}, {}); 

    var labels = []; 

    function loadAllLabels() { 
     labels = rest.query({}, function(result) { 

      var liste = []; 
      for (var idx = 0; idx < result.length; ++idx) { 
       var entry = result[idx]; 
       liste[entry.code] = entry.libelle; 
      }    
      labels = liste; 
     }); 
    } 

    loadAllLabels(); 

    return { 
     getLabels : function() { 
      return labels; 
     }, 

     reloadLabels : function() { 
      loadAllLabels(); 
     }, 

     updateLabel : function(code, newValue) { 
      labels[code] = newValue; 
     } 
    }; 

} 

function scoopLabelFilterFn($log, scoopLabelService) { 

    return function(input) { 
     if (angular.isString(input)) { 
      var libelles = scoopLabelService.getLabels(); 
      var res = libelles[input]; 
      if (res) { 
       return res; 
      } 
      $log.log("scoopLabelFilter: no entry for: " + input); 
      return input; 
     } 
     $log.log("scoopLabelFilter: incorrect parameter type"); 
     return ""; 
    }; 
} 

module.filter("label", [ "$log", "scoopLabelService", scoopLabelFilterFn ]); 
module.factory("scoopLabelService", [ "$resource", "$rootScope", "$timeout", scoopLabelSceFn ]); 

Antwort

0

Eigentlich gibt es nichts konzeptionell falsch mit dem Code.

Die Art und Weise, wie Angular behandelt, hat sich offenbar irgendwo im Zweig 1.3.x geändert. Folglich muss der Code, der die Filterfunktion zurückgibt, modifiziert werden.

Alter Code:

return function(input) { 
... 

Modified Code:

function filterFn(input) { 
... 

filterFn.$stateful = true; 
return filterFn; 

Damit alle Ausdrücke auf den Filter verwendet werden automatisch neu bewertet.