簡體   English   中英

Backbone.js - 根據包含多個關鍵字的Array過濾集合

[英]Backbone.js - Filter a Collection based on an Array containing multiple keywords

我正在使用Backbone.js/Underscore.js來呈現一個HTML表格,當您鍵入文本框時會對其進行過濾。 在這種情況下,它是一個基本的電話簿。
該表的內容來自一個由JSON文件填充的Collection。 下面是JSON文件的基本示例:

[{
    "Name":"Sales and Services",
    "Department":"Small Business",
    "Extension":"45446",
},
{
    "Name":"Technical Support",
    "Department":"Small Business",
    "Extension":"18800",
},
{
    "Name":"Research and Development",
    "Department":"Mid Market",
    "Extension":"75752",
}]

我將文本框值轉換為小寫,然后將其值與Collection一起傳遞給此函數,然后將返回的值分配給新的Collection並使用它重新呈現頁面。

filterTable = function(collection, filterValue) {
    var filteredCollection;
    if (filterValue === "") {
        return collection.toJSON();
    }
    return filteredCollection = collection.filter(function(data) {
        return _.some(_.values(data.toJSON()), function(value) {
            value = (!isNaN(value) ? value.toString() : value.toLowerCase());
            return value.indexOf(filterValue) >= 0;
        });
    });
};

問題是函數是字面的。 要從我的示例中找到“銷售和服務”部門,我必須准確輸入,或者只是“銷售”或“服務”。 我無法輸入“sal serv”,仍然發現它是我想要做的。

我已經編寫了一些javascript,它似乎非常可靠地將文本分成一個單詞數組(現在更新為使用中的代碼)。

toWords = function(text) {
    text = text.toLowerCase();
    text = text.replace(/[^A-Za-z_0-9@.]/g, ' ');
    text = text.replace(/[\s]+/g, ' ').replace(/\s\s*$/, '');
    text = text.split(new RegExp("\\s+"));
    var newsplit = [];
    for (var index in text) {
        if (text[index]) {
            newsplit.push(text[index]);
        };
    };
    text = newsplit;
    return text;
};

我想循環遍歷“split”數組中的每個單詞,並檢查每個單詞是否存在於其中一個鍵/值中。 只要存在所有單詞,它就會傳遞真值迭代器並添加到Collection中並在表中呈現。

所以在我的例子中,如果我輸入“sal serv”,它會發現這兩個字符串都存在於第一個項目的Name中,並且會返回它。
但是,如果我鍵入“銷售業務”,則不會返回,因為盡管兩個值都出現在該項中,但“名稱”部分中不存在相同的兩個單詞。

我只是不確定如何在Backbone / Underscore中寫這個,或者即使這是最好的方法。 我查看了文檔並且不確定哪個函數最簡單。

我希望這是有道理的。 我對Javascript有點新鮮,我意識到我已經潛入了深淵,但學習是有趣的部分;-)
如果需要,我可以提供更多代碼或JSFiddle。

使用下划線的anyall使這相對容易。 這是它的要點:

  var toWords = function(text) {
    //Do any fancy cleanup and split to words
    //I'm just doing a simple split by spaces.
    return text.toLowerCase().split(/\s+/);
  };

  var partialMatch = function(original, fragment) {   
    //get the words of each input string
    var origWords = toWords(original + ""), //force to string
        fragWords = toWords(fragment);

    //if all words in the fragment match any of the original words, 
    //returns true, otherwise false
    return _.all(fragWords, function(frag) {
      return _.any(origWords, function(orig) {
        return orig && orig.indexOf(frag) >= 0;
      });
    });
  };

  //here's your original filterTable function slightly simplified
  var filterTable = function(collection, filterValue) {
      if (filterValue === "") {
          return collection.toJSON();
      }
      return collection.filter(function(data) {
          return _.some(_.values(data.toJSON()), function(value) {
              return partialMatch(value, filterValue);
          });
      });
  };

注意:此方法計算效率非常低,因為它涉及首先循環集合中的所有項目,然后是每個項目的所有字段,然后是該項目值中的所有單詞。 此外,在循環內部聲明了一些嵌套函數,因此內存占用不是最佳的。 如果您有一小組數據,那應該沒問題,但如果需要,可以進行一些優化。 如果我有時間的話,我可能會稍后再回來編輯一下。

/代碼樣本未經測試

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM