2017-07-24 135 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