2013-02-10 62 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