3

示例 jsFiddle


我的模型中有一系列问题,具有以下属性:

  • id:很简单,问题的 ID
  • text:同样,问题的文本
  • parents:此问题所依赖的一系列问题 ID
  • activators:一个字符串数组,当父母的答案是这些值之一时 - 显示这个问题
  • answer : 这个问题的答案
  • visible:一个布尔值,指示此问题是否应在表单上可见

我正在使用ko.mapping将 JSON 字符串(我从 asmx Web 方法中检索)绑定到我的视图模型。

我有一堆没有或因为这些应该始终可见的主要问题,然后是一堆依赖于他们各自父母的依赖问题,在依赖者可见之前具有一定的价值。这可以扩展到依赖家属依赖家属(如果你明白我的意思)。parentsactivators

我最初的想法(因为我正在慢慢地用 knockout.js 到达那里)是订阅answer我的属性,question然后获取一组问题,这些问题取决于刚刚回答的问题。然后查看值,将它们与激活器进行比较,并根据需要显示/隐藏。

viewModel.questions().forEach(function (question) {
    question.answer.subscribe(function (value) {
        var dependents = viewModel.questions().filter(function (q) {
            return q.parents() && q.parents().indexOf(question.id()) !== -1;
        });
        
        dependents.forEach(function (d) {
            if (d.activators() && d.activators().indexOf(value) !== -1) {
                d.visible(true);
            } else {
                d.visible(false);
                d.answer(null);
            }
        });
    });
});

虽然这有效,但我不禁觉得我在这里错过了一个技巧。我必须使用ko.mapping将模型绑定到我的视图模型,因为它已经在 asmx 方法中为我创建了,所以我必须扩展我的视图模型(就像我在这里通过循环遍历所有questions并订阅每个一样。

也许我应该使用ko.computed可见属性,或者我应该创建某种自定义ko.bindingHandlers?我不确定。尝试实现我想要的正确方法是什么?

4

1 回答 1

1

有几种方法可以实现您所追求的,其中一种是使用您提到的自定义绑定。

不管这是否被认为是最“淘汰赛正确”的方式,我不会说,但这是一种不同的方法,至少可能会给你一些想法。这是创建绑定处理程序的一种方法:

ko.bindingHandlers.hideIfIrrelevant = {
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var question = ko.unwrap(valueAccessor());

        if(!question.parents()) {
           $(element).show() // Always show the question if it has no parents
           return false;
        }

        var allQuestions = bindingContext.$root.questions();
        var parents = allQuestions.filter(function (q) {
            return question.parents().indexOf(q.id()) !== -1;
        });

        var shown = false;
        $.each(parents, function(i, parent) {
            if(parent.answer() && question.activators().indexOf(parent.answer()) != -1) {
                shown = true;
                return false;
            }
        });

        if(shown) {
            $(element).show();
        }
        else {
            $(element).hide();
        }
    }
};

这是更新的小提琴。请注意,通过使用自定义绑定,您不再需要将该visible属性作为数据模型的一部分。

于 2013-08-13T19:54:32.457 回答