【问题标题】:JSViews template not updating when the underlying data changes底层数据更改时 JSViews 模板不更新
【发布时间】:2015-09-16 11:17:39
【问题描述】:

当基础数据更改时,我遇到了更新 JSViews 模板的问题。它涉及使用转换器功能将数据链接到基础数据的跨度。当异步回调服务器后底层数据发生变化时,跨度文本不会更新。

标记:

{^{for thedata.myarrayobject}}
    <span data-link="{myconverter:var1:} name{:'theName' + var2}"></span>
{{/for}}

脚本:

$.views.converters({
    myconverter: function (val) {
        switch (val) {
            case 1: 
                return 'Test1'; 
                break;
            case 2: 
                return 'Test2';
                break;
            default: 
                return 'Default';
        }
    }
});

跨度根据 data.myarray 对象中的值在页面加载时正确显示。例如。如果我们有:

thedata.myarrayobject[0].var1='1';
thedata.myarrayobject[0].var2='John';
thedata.myarrayobject[1].var1='2';
thedata.myarrayobject[1].var2='Matthew';

它将加载为:

<span name="theNameJohn">Test1</span>
<span name="theNameMatthew">Test2</span>

但是,如果在异步回调后底层数据发生变化:

thedata.myarrayobject[0].var1='2';
thedata.myarrayobject[0].var2='John';
thedata.myarrayobject[1].var1='1';
thedata.myarrayobject[1].var2='Matthew';

跨度文本保持不变。

我已经调试了 js 代码,并且底层数组参数 'var1' 肯定被设置为新值。我试过打电话:

$.observable(thedata.myarrayobject).refresh(thedata.myarrayobject);

但无济于事。

我显然希望跨度文本随着基础数据的变化而调整 - 任何帮助将不胜感激!

【问题讨论】:

  • 您能否展示您最初如何链接到数据的代码,以及更新到新数据的代码。理想情况下是一个 jsfiddle - 有一个按钮调用您当前的代码以更新到新数据?那我去看看……
  • 嗨@BorisMoore - 只是回答你的问题,我使用的是link()方法,所以数据链接应该可以工作....但是你关于我如何更新数据的第二个问题已经指出了我在正确的方向。我是按照上面的方法做的:直接更新js中的参数值。我刚刚在一个可观察的包装器中尝试过它 - 它已经奏效了!我会在下面贴出来。有什么办法可以给你一些功劳 - 我怀疑如果没有你的评论我会这样做!
  • 我添加了一个答案,以展示您可以“可观察地”合并数据的一些替代方法。

标签: jquery jsrender jsviews data-linking


【解决方案1】:

事实上,要进行更新,您需要选择自己的策略来将新数据(例如来自 Ajax 调用)与以前的数据合并。

但任何合并必须使用“可观察”API 完成 - 以便 JsViews 接收数据链接更新通知并更新您的 UI。

因此,根据您的数据和场景,您可以使用以下任何一种更新:

  1. 一次更改一个叶子值:

    $.observable(thedata.myarrayobject[0]).setProperty("var1", "2");

  2. 一次改变一个对象的叶子值:

    $.observable(thedata.myarrayobject[0]).setProperty(newarrayobject[0]);

    (这将获取任何修改后的属性)

  3. 用新对象刷新整个数组:

    $.observable(thedata.myarrayobject).refresh(newarrayobject);

    (这会将新对象/项目复制到 myarrayobject 中)

  4. 用新的更新 myarrayobject:

    $.observable(thedata).setProperty("myarrayobject", newarrayobject);

    所以在这里你用一个新的数组替换了......

以上任何一项或每一项都将触发使用新数据值的更新。

请注意,上述方法假设您已经下载了一个新的数据数组newarrayobject,其中包含要合并到您之前的@​​987654326@ 中的更新数据。您不需要克隆 newarrayobject 或之前的 myarrayobject

【讨论】:

    【解决方案2】:

    在上面的 BorisMoore 提出了几个问题之后......我更新数据的方式 - 只需将其直接推送到上面的数组参数中:

    thedata.myarrayobject[0].var1='2';
    thedata.myarrayobject[0].var2='John';
    thedata.myarrayobject[1].var1='1';
    thedata.myarrayobject[1].var2='Matthew';
    

    没有工作,我对 $.observable(...).refresh(...) 的调用没有工作,因为我传递了相同的数组:没有触发任何更改来更新标记。

    简单地说,我将数组复制到一个新数组中,更新了值,然后调用了刷新,这样就可以了:

    var myduparrayobject = thedata.myarrayobject.splice();
    
    myduparrayobject [0].var1='2';
    myduparrayobject [0].var2='John';
    myduparrayobject [1].var1='1';
    myduparrayobject [1].var2='Matthew';
    
    $.observable(thedata.myarrayobject).refresh(myduparrayobject);
    

    问题:

    1. 只有数组的可观察更改才会刷新到标记。不仅仅是像我想象的那样简单地更新对象数据。

    2. $.observable(...).refresh(...) 仅在传入引用对象的更改数组时才有效。像我一样传递相同的引用对象(即使它不同于正在显示在标记中)不会触发对模板标记的更改。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多