2017-07-24 183 views
0

對JSViews的另一個問題抱歉。我非常喜歡這個系統,但我偶爾也在苦苦掙扎。JSViews可觀察陣列不刷新

我有一個簡單的模板,只需要更新,以顯示對選擇框改變其數組中的項:

但是,當我改變的模板不被以下更新的數據「isSelected」:

即:

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

如果我改變它

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

它更新得很好。

誰能告訴我什麼,我做錯了:

<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}} 

我的HTML是

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

數組是:

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

我設置的模板:

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

我試過使用$ .view(elem).refresh(),但是因爲我的點擊動作來更新isSelected在模板之外,我找不到正確的「elem」來使用。

編輯 - 添加了實際的更新代碼:

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

回答

1

你的陣列la_configure_list.slice(0)la_configure_list淺拷貝。可觀察數組refresh()方法用於數組更新 - 排序,刪除或添加項目。它被優化以避免不必要的更新。事實上,它分析數組和觸發器移動,插入和刪除它檢測到的任何更改事件。

在你的情況下,雖然你複製了數組,但它是一個淺拷貝,所以數組項是相同的,並且順序沒有改變。因此不會觸發可觀察的數組更改事件。當你使用JSON.parse等你正在克隆副本替換對象,所以現在刷新()認爲所有的項目已被刪除,然後添加新的。

但是你爲什麼不做出任何改變isSelected特性觀察到,沿着線:

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

既然你觀察到的數據鏈接{^{if isSelected}}你應該不需要做任何額外的清爽要麼陣列或視圖...

+0

謝謝你,我更好地理解。我沒有把它作爲一個屬性改變的原因是我實際上正在遍歷類別數組,並查看列表中是否存在選定的類別,並在每個數組項目上更新isSelected。因此,基於搜索條件,arrat中的每個項目都被選擇爲true或false。逐個更新每個版本會不會很慢,而不是最後更新一次?你說刷新用於排序,但這正是我想要做的。有沒有更好的辦法? – grayson

+0

我使用完整的代碼編輯我的問題進行更新/排序 – grayson

+1

只要不向後切換相同的項目並向前切換,您可以在每個項目上使用observable()。propertyChange()。因此,只需使用propertyChange()單擊每個項目即可。如果值已經爲false,則設置propertyChange(...,false)不會觸發事件,如果已經爲true,也不會設置爲true,以便確定。所以這應該是一個合理的方法來訪問每個項目一次... – BorisMoore