2013-02-10 57 views
0

我正在构建一个类似于TFS查询生成器Web界面的高级搜索UI。在客户端实现中使用knockout,并且除了最终验证之外,一切或多或少都能工作,以便基本选择某些必需的项目。如果我选择一个项目然后取消选择该项目,那么它就会给我一个验证错误。这很好,但我希望在按下搜索按钮时验证表单。基因敲除验证 - 高级搜索用户界面

我很确定我需要使用ko.validatedobservable方法,我只是不确定如何。无论如何,我有一个小提琴来看看:http://jsfiddle.net/sstolp/uXBSA/如果任何人有时间或倾向帮助我。我会深表感谢。

谢谢你的时间。

scvm.SearchLine = function() { 
var self = this; 
self.selectedField = ko.observable().extend({ required: true }); 
self.selectedOperator = ko.observable().extend({ required: true }); 
self.firstdate = ko.observable(new Date()); 
self.lastdate = ko.observable(new Date()); 
self.thedate = ko.observable(new Date()); 

return self;}; 

scvm.Criteria = function() { 
var self = this, 
    lines = ko.observableArray([]), 

    // Put one line in by default 
    loadInitialData = function() { 
     lines.push(new scvm.SearchLine()); 
    }, 

    rowcount = ko.computed(function() { 
     return lines().length; 
    }), 

    // Operations 
    addLine = function() { 
     lines.push(new scvm.SearchLine()); 
    }, 

    removeLine = function (line) { 
     lines.remove(line); 
    }, 

    search = function() { 
     var data = $.map(lines(), function (line) { 
      return line.selectedField() ? { 
       selectedField: line.selectedField().searchfield, 
       selectedOperator: line.selectedOperator().name, 
      } : undefined 
     }); 
     alert("Send to server: " + JSON.stringify(data));    
    }, 

    clear = function() { 
     lines.removeAll(); 
    }; 

return { 
    lines: lines, 
    loadInitialData: loadInitialData, 
    rowcount: rowcount, 
    addLine: addLine, 
    removeLine: removeLine, 
    search: search, 
    clear: clear 
}; 
}(); 

回答

0

是的,您所有的SearchLine对象都必须包装成ko.validatedObservable。你也应该执行计算属性,它将检查每个标准行的isValid()并返回全局有效性标志。

scvm.SearchLine = function() { 
    var self = this; 
    self.selectedField = ko.observable().extend({ required: true }); 
    self.selectedOperator = ko.observable().extend({ required: true }); 
    self.firstdate = ko.observable(new Date()); 
    self.lastdate = ko.observable(new Date()); 
    self.thedate = ko.observable(new Date()); 

    return ko.validatedObservable(self); 
}; 

scvm.Criteria = function() { 

    // ... 

    return { 
     lines: lines, 
     loadInitialData: loadInitialData, 
     rowcount: rowcount, 
     addLine: addLine, 
     removeLine: removeLine, 
     search: search, 
     clear: clear, 
     // new property that indicates validity of all lines 
     linesValid: ko.computed(function(){ 
      var items = lines(); 
      for (var i = 0, l = items.length; i < l; i++) 
       if (!items[i].isValid()) return false; 
      return true; 
     }) 
    }; 
}(); 

这个新属性可以在enable可以使用您绑定“搜索”按钮:

<input type="button" 
     data-bind="enable: linesValid, click: search" 
     title="Clicking this button will run a search." 
     value="Search" /> 

我已经修改了你的小提琴。请看:http://jsfiddle.net/ostgals/uXBSA/8/


更新:

此外,我们应该稍微修改Criteria.search方法,因为我们的线阵列包含可观,而不是对象:

 //... 

     search = function() { 
      var data = $.map(lines(), function (line) { 
       line = ko.utils.unwrapObservable(line); 
       return line.selectedField() ? { 
        selectedField: line.selectedField().searchfield, 
        selectedOperator: line.selectedOperator().name, 
       } : undefined 
      }); 
      alert("Send to server: " + JSON.stringify(data));    
     }, 

     //... 
+0

嗨f_martinez。感谢您的答复和小提琴示例。在我发布这个问题之后,我一直在继续研究这个问题,并且实际上提出了一个与您发布的内容略有不同的实现。我注意到的主要区别是你的例子遍历线对象来暴露一个linesValid属性。此外,尽管我的例子中有有效的标准,并且搜索按钮已启用,但当我单击它时,我收到一个错误,即line.selectedField不是函数,而我以前没有收到此消息,而且也没有在我的这个错误。 – Steve 2013-02-10 14:37:04

+0

这里是我更新的小提琴:http://jsfiddle.net/sstolp/uXBSA/ – Steve 2013-02-10 14:37:57

+0

错误发生,因为'line'现在是可观察的,我们应该使用'line()'来访问它的真实接口。我没有测试点击“搜索” - 我的道歉。在我的情况下,解决方法是重写'Criteria.search'方法,然后展开'line'。我已经更新了我的答案。 – 2013-02-10 15:36:11