2013-02-10 4 views
0

Я создаю пользовательский интерфейс расширенного поиска, подобный веб-интерфейсу построителя запросов TFS. Использование нокаута для реализации на стороне клиента и все более или менее работающее, за исключением того, что окончательная проверка для того, чтобы сделать определенные требуемые элементы, в основном выбраны. Это сортирует работу, поскольку дает мне ошибку проверки, если я выбираю элемент, а затем отменю выбор элемента. Это нормально, но я хочу, чтобы форма была подтверждена при нажатии кнопки поиска.проверка нокаута - расширенный поиск пользовательского интерфейса

Я уверен, что мне нужно использовать метод 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() для каждой строки критериев и вернет глобальный флаг достоверности.

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

Я изменил свою скрипку:

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 связывания вас кнопка «Поиск». Посмотрите: http://jsfiddle.net/ostgals/uXBSA/8/


Update:

Кроме того, мы должны немного изменить метод 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

Hi f_martinez. Спасибо за ответ и за пример скрипки. Я продолжал работать над этим после того, как я опубликовал этот вопрос, и на самом деле придумал реализацию, которая немного отличалась от того, что вы опубликовали. Основное отличие, которое я замечаю, заключается в том, что ваш пример выполняет итерацию через объект lines, чтобы выдать свойство linesValid. Кроме того, с вашим примером, хотя у меня есть действующие критерии, и кнопка поиска включена, когда я нажимаю на нее, я получаю сообщение об ошибке, что line.selectedField не является функцией, тогда как я ранее не получал это сообщение, и я не получить эту ошибку в шахте. – Steve

+0

Вот моя обновленная скрипка: http://jsfiddle.net/sstolp/uXBSA/ – Steve

+0

Ошибка возникает из-за того, что 'line' теперь наблюдается, и мы должны использовать' line() 'для доступа к его реальному интерфейсу. Я не тестировал нажатие «Поиск» - мои извинения. Обходной путь в моем случае заключается в том, чтобы переписать метод «Criteria.search» с разверткой 'line' раньше. Я обновил свой ответ. –

Смежные вопросы