更新ObservableArrayItem而不更新Ui 我有如下的Knockout模型
我的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函数下进行更新,在console.log上我可以看到所有在模型端执行的更新都成功运行。为什么arrayItem更新不会传播到UI?
答案 0 :(得分:0)
您无法更新各个索引。您需要将整个数组传递给observable,以便knockout可以运行内部更新代码。
var bt = DetailsViewModel.BType();
bt[index].Amount = totalAmount * 10;
DetailsViewModel.BType(bt);
答案 1 :(得分:0)
除@Robert Krzyzanowski所述之外,您还需要遵循以下模式:
var typeDTOs = ko.observableArray([]);
var underlyingArray = [];
_.each(result.BType, function(typeDTO) {
typeDTO = addPercent(typeDTO, result.Amount);
underlyingArray.push(typeDTO);
}
typeDTOs(underlyingArray);
或者那种效果(为了清楚起见,我在上面使用了underscore.js)。您希望确保不要进入 observable 数组;而是推入底层数组。然后,您可以一次更新可观察数组。如果你不这样做,你将最终为你推入可观察数组的每个项目触发更改事件 - 通常是不受欢迎的。
关于可观察数组的另一个注释
只是侧边栏...如果数组的元素是对象文字,并且您希望UI响应文字属性中的更改,则必须使每个UI绑定属性也是可观察的。