2017-07-24 4 views
0

Entschuldigung für eine andere Frage zu JSViews. Ich liebe dieses System wirklich, aber ich kämpfe gelegentlich.JSViews beobachtbares Array wird nicht aktualisiert

Ich habe eine einfache Vorlage, die nur die Elemente im Array aktualisieren muss auf Auswahlbox Wechsel zeigen:

Allerdings, wenn ich die Daten „isSelected“ die Vorlage zu ändern mit folgendem Grunde nicht aktualisiert wird:

dh:

function someClickFunction(sel) { 
    value = sel.value; 
    .... 
    la_configure_list[0].isSelected = false; 
    $.observable(la_configure_list).refresh(
      la_configure_list.slice(0) 
     ); 
} 

wenn ich es

$.observable(la_configure_list).refresh(
     JSON.parse(JSON.stringify(la_configure_list)) 
         ); 
ändern

es aktualisiert sich gut.

Kann mir jemand sagen, was ich falsch mache:

<script id="la-config-overview-list-template" type="text/x-jsrender"> 
    {^{if isSelected}} 
    <div class="col s12 la_review_list_item" data-index="{{:#index}}"> 
     <div class="card"> 
      <div class="card-content" style="padding: 10px;"> 
       <div class="col s12 m6 l5 xl5"> 
        <h6 style="font-weight: 700;" class="">{{:title}}</h6> 
         <div>Categories:</div> 
         <div> 
          {{for categories}} 
          <span class="chip">{{:#data}}</span> 
          {{/for}} 
         </div> 
        </div> 
        <div class="clearfix"></div> 
       </div> 
      </div> 
     </div> 
    </div> 
    {{/if}} 

mein html

<div id="teacher_la_review_overview_main_wrapper" class="container body-content"> 
    <div class="row" style="margin-bottom: 0;"></div> 
</div> 

das Array ist:

la_configure_list = [ 
{ 
    isSelected:true, 
    title: "Title", 
    categories: ["1", "2"....] 
}, 
.... 
] 

habe ich die Vorlage auf:

$.templates("#la-config-overview-list-template").link("#la_review_list_overview_list_wrapper .row", la_configure_list); 

Ich versuchte mit $ .view (elem) .refresh(), aber wie meine Klickaktion zu aktualisieren IsSelected ist außerhalb der Vorlage, kann ich nicht die richtige "elem" zu verwenden.

EDIT - Added eigentliche Update-Code:

function CategoryUpdate(sel) { 

     var catSelected = sel.value; 
     var catText = sel.options[sel.selectedIndex].text; 

     if (catSelected !== "-1") { 
      for (var cs = 0; cs < la_configure_list.length; cs++) { 
       if (la_configure_list[cs].categories == null) { 
        la_configure_list[cs].isSelected = false; 
        continue; 
       } 
       var categories = la_configure_list[cs].categories; 
       var isFound = false; 
       for (var c = 0; c < categories.length; c++) { 
        var category = categories[c]; 
        if (category === catText) { 

         la_configure_list[cs].isSelected = true; 
         isFound = true; 
        } 
       } 
       if (!isFound) { 
        la_configure_list[cs].isSelected = false; 
       } 
      } 
     } else { 
      for (var x = 0; x < la_configure_list.length; x++) { 
       la_configure_list[x].isSelected = true; 
      } 
     } 

     $.observable(la_configure_list).refresh(
      JSON.parse(JSON.stringify(la_configure_list)) 
     ); 
    } 

Antwort

1

Ihr Array la_configure_list.slice(0) ist eine flache Kopie von la_configure_list. Die observable-Methode refresh() wird für Array-Aktualisierungen verwendet - zum Sortieren, Entfernen oder Hinzufügen von Elementen. Es ist optimiert, um unnötige Updates zu vermeiden. In der Tat analysiert es das Array und löst Bewegungen, Einfügen und Entfernen von Ereignissen für alle Änderungen, die es entdeckt.

In Ihrem Fall, obwohl Sie das Array kopiert haben, ist es eine flache Kopie, so dass die Array-Elemente identisch sind, und die Reihenfolge ist unverändert. Daher wird kein beobachtbares Array-Änderungsereignis ausgelöst. Wenn Sie JSON.parse usw. verwenden, ersetzen Sie das Objekt durch geklonte Kopien, sodass refresh() jetzt berücksichtigt, dass alle Elemente entfernt und dann neue hinzugefügt wurden.

Aber warum Sie eine Veränderung nicht beobachtbar, entlang der Linien von den isSelected Eigenschaften machen: müssen Sie sollten nicht zusätzliche Auffrischung tun

function someClickFunction(sel) { 
    value = sel.value; 
    ... 
    $.observable(la_configure_list[index]).propertyChange("isSelected", false); 
    ... 
} 

Da Sie beobachtbaren Daten-Verknüpfung {^{if isSelected}} entweder das Array oder die Ansichten ...

+0

danke dafür, verstehe ich besser. Der Grund, warum ich es nicht als eine Eigenschaftsänderung mache, besteht darin, dass ich das Kategorie-Array tatsächlich übertrage und sehe, ob eine ausgewählte Kategorie in der Liste ist und die Aktualisierung für jedes Array-Element ausgewählt ist. Jedes Objekt im Arrat hat isSelected basierend auf einer Suchbedingung auf true oder false gesetzt. Wäre es nicht langsam, jedes einzeln einzeln zu aktualisieren, anstatt ein Update am Ende? Sie sagen Refresh wird zum Sortieren verwendet, aber das ist es, was ich versuche zu tun. Gibt es einen besseren Weg? – grayson

+0

Ich habe meine Frage mit dem vollständigen Code für update/sort bearbeitet – grayson

+1

Sie können observable(). PropertyChange() für jedes Element verwenden, solange Sie das gleiche Element nicht redundant hin- und herschalten. Also drücke einfach jedes Element mit einem propertyChange(). Das Festlegen von propertyChange (..., false), wenn der Wert bereits false ist, wird kein Ereignis auslösen, noch die Einstellung von true, wenn bereits true, also ist das OK. Es sollte also ein vernünftiger Weg sein, jeden Gegenstand einmal zu besuchen ... – BorisMoore

Verwandte Themen