【问题标题】:knockout validation unique in list列表中唯一的淘汰赛验证
【发布时间】:2013-10-26 15:34:26
【问题描述】:

我正在尝试使用 ko.validation 验证列表中的条目与列表中的所有其他条目是唯一的,但我在不应该运行验证时遇到了问题。

我有一个可编辑的列表(ko.observableArray),该数组中的每个项目都是一个视图模型,上面有一个ko.observable:

var vm = function (data) {
    var self = this;

    self.items = ko.observableArray();

    _.each(data.words, function (word) {
        self.items.push(new listItemVm({parent: self, word: word.word}));
    });
};

var listItemVm = function (data) {
    var self = this;
    self.parent = data.parent;
    self.word = ko.observable(data.word);
};

然后我向listItemVm.wordko.observable 添加一些验证。我希望每一个都是独一无二的:

var listItemVm = function (data) {
    var self = this;
    self.parent = data.parent;
    self.word = ko.observable(data.word).extend({
        validation: {
            validator: function (name, params) {
                console.log("validating " + name);
                // word we are editing must be different from all other words

                // uncommenting this next line causes the behaviour
                // I would expect because params.parent.items() 
                // is not called
                //return true;

                var allWords = params.parent.items();

                // exclude current view model we are editing
                var otherWordViewModels = _.filter(allWords, function (row) {
                    return row !== params.currentRow;
                });

                var otherWords = _.map(otherWordViewModels, function (item) {
                    return item.word();
                });

                return !_.contains(otherWords, name);
            },
            message: 'Must be unique',
            params: {
                currentRow: self,
                parent: self.parent
            }
        }
    });
};

我给它一些数据,并用一些 HTML 包装它:http://jsfiddle.net/9kw75/3/

现在,这工作 - 验证运行正确,当两个输入的值相等时显示无效 - 但请查看该小提琴的控制台。为什么验证例程在加载时会运行三五次,为什么只有一个值更新时两个字段都验证?

  • 页面加载
    • 预期:验证对每个输入字段运行一次。
    • 实际:一个输入验证运行 3 次,另一个输入运行 2 次。
  • 值更新(任一输入字段)
    • 预期:仅对更改的输入字段运行验证
    • 实际:两个输入字段的验证运行

值得注意的是,只有在验证器中读取params.parent.items() 后才会观察到这种奇怪的行为。如果 return 被注释掉,我期望的行为就会被观察到。

【问题讨论】:

  • 我不明白 - 那个小提琴工作正常吗?
  • @PWKad 我不这么认为。消息显示正确,但打开控制台并查看验证例程何时运行。更新了问题以使这一点更清楚。

标签: javascript knockout.js knockout-validation


【解决方案1】:

我相信它的工作方式是在计算的 observable 中使用“验证器”函数。因此,任何在执行时读取的 observables 现在都是计算的 依赖项。由于您在此函数中读取每个项目的 word observable,因此每个项目都会触发对所有其他项目的验证。

它以这种方式工作是有道理的,但对于您的特定应用程序来说,它没有意义。你可以使用peek 来读取 observables 而不会触发依赖检测:

var allWords = params.parent.items.peek();

// ...

var otherWords = _.map(otherWordViewModels, function (item) {
    return item.word.peek();
});

【讨论】:

    猜你喜欢
    • 2012-02-18
    • 2013-10-18
    • 2012-10-17
    • 2011-08-09
    • 1970-01-01
    • 2012-11-04
    • 1970-01-01
    • 2017-01-27
    • 1970-01-01
    相关资源
    最近更新 更多