对象键值更改时刷新 UI - 挖空

Refresh UI when object key value change - Knockout

抱歉,刚从 Knockout.js 开始问一个菜鸟问题。我有一个对象数组,我想在对象 属性 favorite: 更改时更新视图,但每次我单击触发更改的图标时,什么都没有发生。当我将新对象添加到数组时,UI 会重新呈现。我真的很感激这方面的帮助。谢谢

<div id="container" data-bind="foreach:savedSearches">
  <div class="save-search-item" data-bind="attr:{'data-name': $data.name, 'data-id':$data.id, 'favourite':$data.favorite() === 1}">
    <div data-bind="text: $data.name"></div>
    <div class="icons">
      <a href="#" class="favourite-search">
        <i class="fas fa-star" data-bind="css: {favourite: $data.favorite() === 1}"></i>
      </a>
      <a href="#" class="edit-search">
        <i class="fas fa-edit"></i>
      </a>
      <a href="#" class="delete-search">
        <i class="fas fa-trash-alt"></i>
      </a>
    </div>
  </div>
</div>

var searches = [
    {
    activation_time: null,
    activation_time_ms: null,
    favourite: 1,
    enabled: 1,
    id: 66,
    name: "adfdfafs"
  },
  {
    activation_time: null,
    activation_time_ms: null,
    favourite: 0,
    enabled: 1,
    id: 66,
    name: "adfdfafs"
  }
];

ko.applyBindings(AppViewModel, $('#container'));

function AppViewModel(data) {
  self.savedSearches = ko.observableArray([]);
  self.favourite = ko.observable();

  self.populateSavedSearches = function(data) {
    data.forEach(function(search) {
      search.favorite = ko.observable();
    });

    self.savedSearches(data);
  }
}

$('.favourite-search').on('click', function(e) {
  e.preventDefault();
  e.stopPropagation();

  // get parent element with id
  var parent = e.currentTarget.closest('.save-search-item');
  var searchId;
  var isFavourite = false;

  if (parent) {
    searchId = parseInt(parent.getAttribute('data-id'));
    isFavourite = parent.getAttribute('favourite');

    searches.map(function(search) {
      if (search.id === searchId) {
        search.favorite = 0;
        ko.populateSavedSearches(search);
      }
    });
  }
});

使用 knockout 时,不应通过 jQuery 添加自己的事件侦听器。

在这种情况下,使用 click 绑定来响应用户行为。

我做了最低限度的工作来使您的代码片段正常工作,但我认为它明白了要点:

  • 您已经发现必须使 favorite 属性 可观察!伟大的开始
  • 我在每个搜索中添加了一个 toggle 函数,在 10
  • 之间交换 favorite 可观察值
  • 视图 中,我添加了一个调用 toggle
  • click 绑定
  • 视图中,我将您的favourite属性绑定移动为css绑定。这确保收藏的搜索获得 favourite class
  • 在 CSS 中,我将 .favourite 个元素设置为黄色背景。
  • applyBindings 中,我使用 new 创建一个新的视图模型并使用 [0]
  • 传递应用程序容器

您可以在下面的代码片段中看到这些变化。

var searches = [
    {
    activation_time: null,
    activation_time_ms: null,
    favourite: 1,
    enabled: 1,
    id: 66,
    name: "adfdfafs"
  },
  {
    activation_time: null,
    activation_time_ms: null,
    favourite: 0,
    enabled: 1,
    id: 66,
    name: "adfdfafs"
  }
];

ko.applyBindings(new AppViewModel(searches), $('#container')[0]);

function AppViewModel(data) {
  const self = this;
  self.savedSearches = ko.observableArray([]);
  self.favourite = ko.observable();

  self.populateSavedSearches = function() {
    data.forEach(function(search) {
      search.favorite = ko.observable(search.favorite);
      search.toggle = function() {
        search.favorite(search.favorite() ? 0 : 1);
      }
    });

    self.savedSearches(data);
  }
  
  self.populateSavedSearches();
}
.favourite { background: yellow }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div id="container" data-bind="foreach: savedSearches">
  <div class="save-search-item" data-bind="
    click: toggle,
    attr: {
      'data-name': $data.name,
      'data-id':$data.id
     },
     css: { 'favourite': $data.favorite() === 1 }
  ">
    <div data-bind="text: $data.name"></div>
    <div class="icons">
      <a href="#" class="favourite-search">
        <i class="fas fa-star" data-bind="css: {favourite: $data.favorite() === 1}"></i>
      </a>
      <a href="#" class="edit-search">
        <i class="fas fa-edit"></i>
      </a>
      <a href="#" class="delete-search">
        <i class="fas fa-trash-alt"></i>
      </a>
    </div>
  </div>
</div>