【问题标题】:update ui when array element is updated更新数组元素时更新 ui
【发布时间】:2021-01-07 07:23:27
【问题描述】:

我正在尝试在更新数组属性时更新 UI,

我有颜色数组,我试图更新颜色数组中的红色,但它不会更新 UI

var ViewModel = function() {
  this.self = this;

  self.colors = ko.observableArray([
    { color: "red", test: "aaa" },
    { color: "blue", test: "bbb" },
    { color: "yellow", test: "ccc" }
  ]);

  self.replaceIt = function() {
    const result = self.colors().filter(c => c.color === "red");
    result[0].color = "green";
    for (var i = 0; i < self.colors().length; i++) {
      self.colors.replace(self.colors()[0], result[0]);
    }
  };
};

ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<ul data-bind="foreach: colors">
  <li>
    <span data-bind="text:color"></span>
    <span data-bind="text:test"></span>
  </li>
</ul>

<br/>
<br/>

<button data-bind="click:replaceIt">Replace It</button>

结果 UI 始终显示

red aaa
blue bbb
yellow ccc

但是当我将属性红色更新为绿色时,我想更新 UI

green aaa
blue bbb
yellow ccc

【问题讨论】:

    标签: knockout.js


    【解决方案1】:

    由于在您的设置中,color 属性本身是不可观察的,
    您必须使用全新的数组项更新 observableArray 才能触发更改跟踪。

    self.colors.replace(result, { color: "green", test: result.test });
    

    请参阅下面的工作演示。

     var ViewModel = function() {
    
        this.self = this;
    
        self.colors = ko.observableArray([
            {color: 'red' , test:"aaa"},
            {color: 'blue' , test:"bbb"},
            {color: 'yellow' , test:"ccc"}    
            ]);
    
        self.replaceIt = function() {
    
            const result = self.colors().filter(c => c.color ==="red")[0];
            if (result)    
            {   
                self.colors.replace(result, { color: "green", test: result.test });
            }
        };
    };
    
    ko.applyBindings(new ViewModel());
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
    
    <ul data-bind="foreach: colors">
        <li>
        <span data-bind="text:color"></span>   
        <span data-bind="text:test"></span>
    
        </li>
    </ul>
    <br/>
    <br/>
    
    <button data-bind="click:replaceIt">Replace It</button>

    【讨论】:

    • 感谢@pfx 的回复,但我想知道我是否有一个像 30 属性这样的大对象,而不仅仅是问题中提到的两个属性,我只想更新一个属性,我应该映射所有其他属性吗? 29 个属性,就像您在答案中所做的那样,或者应该是一种动态映射它们而无需逐个编写它们的方法
    • @ali 我将为存储在 colors 数组中的对象创建一个视图模型,具有可观察的 color 属性。这样做,只需将 color 更改为绿色即可更新 UI,您不必通过 replace 操作数组。两种解决方案都可以,这是一个偏好问题。
    • @ali 另一种可能性是使用ko.mapping 来帮助映射/转换大型 dto 到淘汰视图模型
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 1970-01-01
    • 2011-12-25
    • 2015-06-10
    • 1970-01-01
    相关资源
    最近更新 更多