Knockout: Mapping of data not working with filter

2019-08-15 11:14发布

问题:

Basically I'm very new to Knockout. I have been trying tons and tons of examples and I'm going insane now. What I'm doing is not difficult. But, it still doesn't work.

I'm trying to take in data, map it to an object (?), then using some observables to do different filtering. This data will never need to be written back to the server, it is for consumption only.

My broken example: http://jsfiddle.net/boyus/qTb5Q/3/

function Item(id, firstName, lastName, expertise, img, tag) {
    this.id = ko.observable(id);
    this.firstName = ko.observable(firstName);
    this.lastName = ko.observable(lastName);
    this.expertise = ko.observable(expertise);
    this.img = ko.observable(img);
    this.tag = ko.observable(tag);
    this.fullName = ko.dependentObservable(function() {
        return this.firstName() + " " + this.lastName();
    }, this);
    this.expertPath = ko.dependentObservable(function() {
        return "http://www.example.com/user/" + this.id();
    }, this);
    this.imgPath = ko.dependentObservable(function() {
        return "http://img835.imageshack.us/img835/5116/" + this.img();
    }, this);
}

var viewModel = {
    items: ko.observableArray([]),
    filter: ko.observable()
};

//ko.utils.arrayFilter - filter the items using the filter text
viewModel.filteredItems = ko.dependentObservable(function() {
    var filter = this.filter().toLowerCase();
    if (!filter) {
        return this.items();
    } else {
        return ko.utils.arrayFilter(this.items(), function(item) {
            return (item.fullName().indexOf(filter) > -1);
        });

    }, viewModel);


var JSONdataFromServer = '[{"id":"1","firstName":"Bill","lastName":"Nye","expertise":"Science Guy", "img":"emptyprofile.png","tag":"environment"},{"id":"54","firstName":"John","lastName":"Dow","expertise":"Software Creation","img":"emptyprofile.png","tag":"software"},{"id": "544","firstName":"Pete","lastName":"Dragon","expertise":"Magic (and Sparkles)","img":"emptyprofile.png","tag": "environment"}]';

var dataFromServer = ko.utils.parseJson(JSONdataFromServer);

//do some basic mapping (without mapping plugin)
var mappedData = ko.utils.arrayMap(dataFromServer, function(item) {
    return new Item(item.id, item.firstName, item.lastName, item.expertise, item.img, item.tag);
});


viewModel.items(mappedData);

ko.applyBindings(viewModel);​

Thanks for all the help in advance.

If it helps (aka my code will never work) my future updates to this code will be:

  • Filtering by category (I think I have this working in another example, but not with an array of categories for each expert)
  • Filtering by first letter of the last name
  • All 3 filtering types must be on the same page

回答1:

For the specific problems with your current fiddle:

  • you were missing a brace in the filteredItems at the end of the else statement
  • you can't call toLowerCase() on null or undefined. I changed it to initialize filter as an empty string.
  • the comparison probably should convert fullName to lower case as well.

Updated sample here: http://jsfiddle.net/rniemeyer/qTb5Q/4/



标签: knockout.js