JsViews:Update/refresh 多个“select”上的数据同时动态 - 使用 depends=

JsViews: Update/refresh data on multiple `select's` dynamically simultaneously - using depends=

我无法同时动态地将多个 select's 上的可观察数据发送到 update/refresh。

渲染两个以上 select's 时,过滤器只显示未在另一个 select 中选择的那些 option's。因此,如果在一个 select 中选择了一个选项,则相同的选项不应出现在另一个 select's.

...初始页面加载时,选项被正确过滤。

...在 select 更改时,选项没有正确重新过滤,我认为是因为选项在数据值更新之前被过滤了(但我不确定它们是否会全部刷新).

{^{for selectedVals ~selectedVals=selectedVals ~listVals=listVals}}
     <select data-link="id">
        {^{for ~catFilter(id, ~listVals, ~selectedVals)}}
            <option data-link="value{:id} {:category}"></option>
        {{/for}}
    </select>
{{/for}}
$.views.helpers({
     catFilter: function(id, listVals, selectedVals) {
          return listVals.filter(item1 =>
              !selectedVals.some(item2 => (item2.id) === item1.id && item1.id !== id));
     }
})

我不太确定最好的方法,并尝试使用内置 filter=... mapDepends="id"convertBack...但收效甚微。

现在我正在侦听可观察到的变化并刷新数组...但是它不起作用(不确定我这样做是否正确)。

$(data[0].selectedVals).on("propertyChange", changeHandler)
function changeHandler(ev, eventArgs) {
     $.observable(data[0].selectedVals).refresh(data[0].selectedVals)
}

这是一个演示:https://jsfiddle.net/alnico/tr6wfn13/

任何 help/insight 将不胜感激。

最好的方法是不要尝试触发数据上的 arrayChange 事件,而是在 selectedVals 项之一时只刷新 {^{for ~catFilter(id, ~listVals, ~selectedVals)}} 标记的内容id.

有一个明显的变化

您可以通过在 ~catFilter() 辅助函数(参见 Declaring dependencies for a computed observable)或 {^{for}} 标记本身上指定 depends 属性 来实现.

事实上,您的 'depends' 路径可以使用通配符 .[],这样您就可以在数组中的任何项目上收听给定的 属性。在您的情况下,它将是 depends = "~selectedVals.[].id" - 它将仅侦听数组中某个项目的 id 属性 中的更改,并将触发对 [=24= 内容的刷新] 标签。

那个 .[] 通配符缺少详细的文档(我希望在某个时候添加它)但是你可以看到它在示例中使用,例如 here.

您可以通过两种方式添加该依赖项:

{^{for}} 标签上声明:

{^{for ~catFilter(id, ~listVals, ~selectedVals) depends="~selectedVals.[].id"}}

或以编程方式在可观察的辅助函数上:

$.views.helpers.catFilter.depends = "~selectedVals.[].id";

如果您在 {^{for}} 标签上设置 filter=... 函数而不是使用计算助手进行过滤,则可以使用相同的方法。您只需指定取决于 属性 您的过滤函数:

{^{for ~listVals filter=~listFilter}}
  <option data-link="value{:id} {:category}"></option>
{{/for}}

与帮手:

listFilter: function(item1) {
  return !this.ctxPrm("selectedVals").some(
    item2 => (item2.id) === item1.id && item1.id !== this.view.data.id
  );
}

然后将 depends="~selectedVals.[].id" 添加到标签(与 catFilter() 版本一样),或者在 listFilter 函数中设置它,如下所示:

$.views.helpers.listFilter.depends = "~selectedVals.[].id";

这里 version of your jsfiddle 展示了这些替代方法。