对象键值更改时刷新 UI - 淘汰赛

Posted

技术标签:

【中文标题】对象键值更改时刷新 UI - 淘汰赛【英文标题】:Refresh UI when object key value change - Knockout 【发布时间】:2021-10-09 13:02:49 【问题描述】:

抱歉,我刚开始使用 Knockout.js。我有一个对象数组,我想在对象属性喜爱时更新视图:更改但每次单击触发更改的图标时都没有任何反应。当我向数组中添加新对象时,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);
      
    );
  
);

【问题讨论】:

【参考方案1】:

当使用敲除时,你不应该通过 jQuery 添加自己的事件监听器。

在这种情况下,使用click 绑定对用户行为做出反应。

为了让你的 sn-p 工作,我做了最起码的工作,但我认为它明白了这一点:

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

您可以在下面的 sn-p 中看到这些变化。

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>

【讨论】:

感谢您的快速回答。问题是我需要点击事件,因为当点击收藏图标时,我必须调用数据库将 .save-search-item 设置为收藏。 因此,当我拨打电话以使搜索成为收藏夹时,我会使用 ko.favourite(1) 并取消设置 ko.favourite(0) 以使用该 ID 进行搜索,然后我调用 ko。 populateSavedSearches(arrayOfAllSeraches) 改变值但不重新渲染 UI 终于成功了。我需要对你的代码做一些小的修改,但现在它可以工作了:D 谢谢

以上是关于对象键值更改时刷新 UI - 淘汰赛的主要内容,如果未能解决你的问题,请参考以下文章

吃透Redis:缓存淘汰篇-LFU算法

吃透Redis:缓存淘汰篇-LFU算法

在不丢弃其余键的情况下更改对象的键值

实体框架出错:AcceptChanges无法继续,因为对象的键值与ObjectStateManager中的另一个对象冲突

调试 C# 时为啥不能更改字典键值对的计数?

如何更改状态挂钩中的多个键值?