2013-11-13 2 views
4

Просто входите в javascript и knockout.js. Я нашел несколько примеров того, что я пытаюсь выполнить. И я чувствую, что есть небольшая синтаксическая ошибка, которую я могу игнорировать. Я пытаюсь отфильтровать уже возвращенный набор (this.tasks) с сервера через ajax/json. У меня это нормально работает. Я бы хотел, чтобы пользователи могли переключаться между полными и неполными задачами.Синтаксис фильтра нокаута. Js Array

Я переключил код, чтобы просто запустить цикл foreach на tasksFiltered. «this.done» является либо истинным, либо ложным.

шаблон Задача

var taskModel = function(id, title, description, done){ 
    var self = this; 
    this.id = ko.observable(id); 
    this.title = ko.observable(title); 
    this.description = ko.observable(description); 
    this.done = ko.observable(done); 

    this.showEdit = ko.observable(false); 
    this.titleUpdate = ko.observable(false); 
    this.descriptionUpdate = ko.observable(false); 
}; 

Page Модель

var pageModelTasks = function(){ 
    var self = this; 
    this.task_title = ko.observable(""); 
    this.task_description = ko.observable(""); 
     this.task_title_focus = ko.observable(true); 
    this.tasks = ko.observableArray([]); 

    this.tasksFiltered = ko.computed(function() { 
     return ko.utils.arrayFilter(this.tasks, function(Task) { 
     return Task.done == true; 
     }); 
    }); 

    // CRUD functions excluded 
}; 

это не работает.

ответ

10

Две небольшие поправки к вашему коду. Во-первых, как отметил @XGreen, вам нужно передать значение массива, , а не экземпляр observableArray, как первый параметр функции arrayFilter. Наконец, поскольку Task.done является наблюдаемым, вам нужно вызвать участника, чтобы получить значение. Вот модифицированный код:

this.tasksFiltered = ko.computed(function() { 
    return ko.utils.arrayFilter(this.tasks(), function(Task) { 
     return Task.done() === true; 
    }); 
}); 
+0

Рад помочь :) –

+0

Вам не хватает «этого» аргумента в вычисляемый или используйте «self.tasks()» вместо «this .задания()" –

1

Если вы хотите использовать нокаут arrayFilter, вам нужно не только вернуть внутреннее значение, например, то, которое у вас есть (return task.done == 'true';), но вам также нужно вернуть сам массив Filter, чтобы получить сбор фильтра из этого .filter.

Посмотрите на пример ниже:

//filter the items using the filter text 
viewModel.filteredItems = ko.computed(function() { 
    var filter = this.filter().toLowerCase(); 
    if (!filter) { 
     return this.items(); 
    } else { 
     return ko.utils.arrayFilter(this.items(), function(item) { 
      return ko.utils.stringStartsWith(item.name().toLowerCase(), filter); 
     }); 
    } 
}, viewModel); 

ваш метод фильтра в настоящее время не является даже синтаксически корректен.

+0

обновил код, просто запустить "Еогеасп" метод связывания на tasksFiltered. Добавлен возврат к функции. Все еще не уверен, что мне не хватает. – aibarra

+0

ОК, код, кажется, работает во всех, кроме возврата Task.done == false; линия. Сравнения, похоже, не работают, если я не сделаю это до! ==, тогда все записи показывают. Так что я думаю, что моя проблема где-то здесь, и это независимо от какого-либо поля, которое я делаю – aibarra

1

У второго решения есть проблема с методом ko.utils.stringStartsWith.

ko.utils.stringStartsWith отсутствует в файле выпуска.

Вы можете использовать этот код:

var stringStartsWith = function (string, startsWith) {   
     string = string || ""; 
     if (startsWith.length > string.length) 
      return false; 
     return string.substring(0, startsWith.length) === startsWith; 
    }; 

See Issue Link

0

Это может помочь вам

if (myList().length > 0) { 
    var text= this.filter().toLowerCase(); 
    return ko.utils.arrayFilter(myList(), function (item) { 
       if (item.Label.toLowerCase().indexOf(text) > -1 || item.Desc.toLowerCase().indexOf(text) > -1) { 
        return true; 
       } 
       else { 
        return false; 
       } 
      }); 
} 
Смежные вопросы