更新了“可观察数组”下的项目未传播到 UI

Update on Items under ObservableArray NOT propagated to UI

本文关键字:项目 传播 UI 观察 可观察数组 数组 更新      更新时间:2023-09-26

ObservableArrayItem 中的更新未更新 UI我有如下所示的淘汰模型

我的 c# 数据模型如下所示

   public class DTO
    {       
        public decimal Amount { get; set; }
        public decimal AmountLeft { get; set; }      
        public TypeDTO[] BType { get; set; }
    }
       public class TypeDTO
    {
        public string Description { get; set; }
        public decimal Amount { get; set; }
    }

这是我的JS,对于初始加载,它可以正常工作

var DetailsViewModel;
   $.ajax({
        url: "url",
        type: "get",
        contentType: "application/json",
        success: function (result) {
            for (i = 0; i < result.BType.length; i++) {
                addPercent(result.BType[i], result.Amount);
            }
            DetailsViewModel = ko.mapping.fromJS(result);
            ko.applyBindings(DetailsViewModel, $("#elem-box").get(0));

    });
function addPercent(BType, totalAmount)  //**adds two new fields to what server sends**
    {
        BType.Percent = ko.computed(function () {
            return ((BType.Amount / totalAmount) * 100).toFixed(2) + '%';
        });
        BType.Ratio = ko.computed(function () {
            return ((BType.Amount / totalAmount) ).toFixed(2);
        });
    }

在初始 UI 绑定上,它可以完美运行。 后来当我在 JavaScript 中更新DetailsViewModel.BType数组时,它不会在 UI 中更新。

某些事件传递的触发器 UI 元素的索引对应于 BType 数组

var totalAmount = DetailsViewModel.Amount();
DetailsViewModel.BType()[index].Amount = totalAmount * 10;
DetailsViewModel.AmountLeft = totalAmount - DetailsViewModel.BType()[index].Amount;
addPercent(DetailsViewModel.BType()[index], totalAmount);

对 BType 数组所做的更新都没有在 UI 端更新,也没有在控制台上的 addPercent 函数下进行的更新.log我可以看到模型端的所有更新都成功运行。 为什么数组项更新不传播到 UI?

无法更新单个索引。您需要将整个数组传递给可观察量,以便 KNOCKOUT 可以运行内部更新代码。

var bt = DetailsViewModel.BType();
bt[index].Amount = totalAmount * 10;
DetailsViewModel.BType(bt);

根据Krzyzanowski@Robert所说的话,你需要遵循以下模式:

var typeDTOs = ko.observableArray([]);
var underlyingArray = [];
_.each(result.BType, function(typeDTO) {
    typeDTO = addPercent(typeDTO, result.Amount);
    underlyingArray.push(typeDTO);
}
typeDTOs(underlyingArray);

或类似的东西(我使用了下划线.js上面只是为了清楚起见)。 你要确保不要推入你的可观察数组;而是推送到底层阵列中。 然后,您可以一次更新所有可观察数组。 如果你不这样做,你最终会为你推入可观察数组的每个项目触发更改事件——通常是不希望的。

关于可观察数组的另一个说明

只是一个侧边栏...如果数组的元素是对象文本,并且您希望 UI 响应文本属性中的更改,则还必须使每个 UI 绑定属性也成为可观察属性。