检查observableArray中是否存在某个项

5
为什么检查重复的 Artist 总是返回false
请参考此JSFiddle示例Knockout 代码:
$(function() {

  function Artist(name) {
    this.name = name;
  }

  function ViewModel() {
    var self = this;
    self.favoriteArtists = ko.observableArray([]);
    self.artistToAdd = ko.observableArray("");
    self.addArtist = function () {
      var newFavoriteArtist = new Artist(self.artistToAdd());
      console.log("New Favorite Artist: " + newFavoriteArtist.name);
      var artistExists = self.favoriteArtists.indexOf(newFavoriteArtist) > 0;
      console.log("Artist Exists: " + artistExists);
      if(!artistExists) {
          self.favoriteArtists.push(newFavoriteArtist);
          console.log("A new artist has been added:" + self.artistToAdd());
      } else {
        console.log("Artist already in favorites.");
      }
    };
  }  
  ko.applyBindings(new ViewModel());
});

HTML

<h1>Favorite Artists</h1>
<p>Currently, your favorite artists include:</p>
<ul data-bind="foreach: favoriteArtists">
    <li> <span data-bind="text: name"></span>
    </li>
</ul>
<p>Enter the name of a new artist:</p>
<input data-bind="value: artistToAdd" />
<button data-bind="click: addArtist">Add</button>


1
你为什么要使用observableArray - KSFT
@KSFT 你是对的,self.artistToAdd 应该是 ko.observable("") 而不是 ko.observableArray(""),这就是导致检查始终返回 false 的原因。 - Jonathan Kittell
好的,但为什么favoriteArtists是一个observableArray而不是普通数组? - KSFT
1
@KSFT 我在HTML源代码中使用数据绑定来显示数组中的Artist项目列表。 - Jonathan Kittell
5个回答

8

您的检查应该是以下之一:

self.favoriteArtists.indexOf(newFavoriteArtist) >= 0

self.favoriteArtists.indexOf(newFavoriteArtist) != -1

self.favoriteArtists.indexOf(newFavoriteArtist) > -1

您正在检查它是否大于零。这意味着如果它在位置0,artistExists将被设置为false,因为零不大于零。
但是,这仍然不起作用。数组中充满了Artist对象,无法通常搜索该对象,因为您搜索的对象与数组中的对象不同,即使它们具有相同的name值。

5

我不确定,但是self.favoriteArtists.indexOf(newFavoriteArtist) > 0;看起来有点奇怪,我预计应该是-1。如果你不断添加相同的艺术家,它会一直认为其不存在。

同时,你还在不断创建新的对象,这些对象并不在列表中。默认情况下,(复杂)对象不相等。


2
糟糕,忽略了你的回答。在我看来,这是正确的。你可以包含这个 JSFiddle并可能还有一小段它的代码。 - Jeroen

3
您可以对数组进行筛选并检查其长度是否为零。如果不为空,则包含该项。
return favoriteArtists.filter(function(data) {
      return data === newFavoriteArtist;
    }).length !== 0;

1

看一下这段代码:

var newFavoriteArtist = new Artist(self.artistToAdd());
// ...
var artistExists = self.favoriteArtists.indexOf(newFavoriteArtist) > 0;

每次创建一个新对象(new Artist),您就会尝试在旧对象的列表(favoriteArtists)中查找新对象 - 这时您的代码无法按预期工作。
相反,您可以添加另一个函数,通过名称(或其他唯一属性)找到艺术家,并澄清该项是否已添加。

0
更好的做法是在找到第一个元素后停止迭代,而不是遍历整个集合(因此使用 find 而不是 filter):
return favoriteArtists.find(function(data) {
  return data === newFavoriteArtist;
}) !== null;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接