检查一个项目是否存在于 observableArray 中

Check if an item exists in an observableArray

为什么检查重复 Artist 总是返回 false

请参阅此 JSFiddle 以获取可运行的演示。

淘汰代码

$(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>

不确定,但是 self.favoriteArtists.indexOf(newFavoriteArtist) > 0; 似乎有点奇怪,我希望那里有一个 -1。如果您不断添加同一位艺术家,它会一直认为它不存在。

并且您不断制作不在列表中的新对象。默认情况下,(复杂)对象彼此不相等。

您的支票应该是以下之一:

self.favoriteArtists.indexOf(newFavoriteArtist) >= 0

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

self.favoriteArtists.indexOf(newFavoriteArtist) > -1

您正在检查它是否大于零。这意味着如果它在位置 0,artistExists 将被设置为 false 因为零不大于零。

不过还是不行。数组中填满了Artist个对象,不能正常查找,因为你查找的对象和数组中的对象不一样,即使它们有相同的name值。

看看这部分代码:

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

每次创建新对象时 (new Artist)。然后您尝试在旧对象列表中查找新对象 (favoriteArtists) - 此处您的代码无法按预期工作。

相反,您可以添加一些其他功能,它允许您按名称(或其他一些独特的 属性)查找艺术家,并澄清之前是否添加过此项目。

您可以过滤数组并检查其长度是否为零。如果它不为空,则它包含该项目。

return favoriteArtists.filter(function(data) {
      return data === newFavoriteArtist;
    }).length !== 0;

更好的方法是在找到第一个元素后停止迭代,而不是遍历所有集合(因此使用查找,而不是过滤器):

return favoriteArtists.find(function(data) {
  return data === newFavoriteArtist;
}) !== null;