how to search with knockout

2019-09-01 07:22发布

i am trying to make a very simple search using knockout in a Durandal project. Demo in Jsfiddle

  1. What am i doing wrong here?
  2. Is there a better way to implement search ?

     var url = "https://www.googleapis.com/books/v1/volumes?q=the+Cat+In+The+Hat";
    
        $.getJSON(url, function (data) {
            console.log(data.items);
            var books = data.items;
       var viewModel = {
        query: ko.observable('')
        };
         viewModel.model = ko.mapping.fromJS(data.items);
       viewModel.books = ko.dependentObservable(function() {
        var search = this.query().toLowerCase();
        return ko.utils.arrayFilter(books, function(book) {
            return book.kind.toLowerCase().indexOf(search) >= 0 || book.brewery.toLowerCase().indexOf(search) >= 0 || book.style.toLowerCase().indexOf(search) >= 0;
        });
    }, viewModel);
            ko.applyBindings(viewModel);
        });
    

标签: knockout.js
1条回答
小情绪 Triste *
2楼-- · 2019-09-01 08:08

1: What am i doing wrong here?

There are few mistakes in your code which is clearly visible to me:

  • You added ko.mapping plugin before knocout.js. Mapping plugin should added after knockout.js.
  • In your js code you are using JSON.stringify which convert the response json object to json string. No need to convert it, just use as it is.

2: Is there a better way to implement search ?

I have created a fiddle to demonstrate a slightly better approach of searching according to your scenario.

Note: I used the latest stable version of knockout i.e. 3.0.0 and i recommend you to always use the latest version. You used dependentObservable in your code but Since Knockout 2.0, dependent observables are now called computed observables.

Fiddle (If fiddle not works than you should provide your api key in javascript code)

Main view model

function viewModel()
{
  var self = this;
  var key = "your api key";

  self.query = ko.observable("the cat is in the hat").extend({ throttle: 500 });

  self.books = ko.observableArray();

  self.get = function() { 
     $.ajax({
            url: "https://www.googleapis.com/books/v1/volumes",
            data: { q: self.query(), key: key },
            type: "GET",
            success: function (response) {
                ko.mapping.fromJS(response.items, {
                    create: function(options) {
                       return new book(options.data);
                    }
                }, self.books);
            }
      });
  };

  self.search = ko.computed(function() {
    if(self.query() !== "")
      self.get();
  });
}

Book object

function book(data)
{
  var self = this;

  ko.mapping.fromJS(data, {}, self); 

  //here you can add extra properties in book object if needed
}

Apply bindings

$(function(){
  var vm = new viewModel();
  vm.get();                   //get initial data
  ko.applyBindings(vm);
});

Note: Currently this code is not handling proper messages on error, on books not found, input query validation etc etc. You should handle it by yourself in order to provide better user experience.

Edit

I updated your code in fiddle check this its working.

查看更多
登录 后发表回答