javascript - Knockout.js - 更新父 View 模型中的数组,并使用第二 View 模型中的值

标签 javascript arrays mvvm knockout.js viewmodel

所以我有 2 个 View 模型,一个包含我使用的数组,该数组将 dataList 中的每个数据节点绑定(bind)到表单,另一个用作每个数据节点的模型。我正在尝试使用第二个 View 模型中的数据更新第一个 View 模型中的数组:

HTML:

<div data-bind="foreach:mainArray">
    <select data-bind="options: $root.ourTypes, optionsValue: 'ID', optionsText: 'Name', value: $data.OurTypeId"></select>
</div>

JavaScript:

var dataList = [        
    { OurTypeId: 4 }, // there are other values here... 
    { OurTypeId: 2 }, // and here...
    { OurTypeId: 3 }  // and here...
];
var ourTypes = [
    { ID:"1", Name:"None", Limit:0 },
    { ID:"2", Name:"Fruits", Limit:5 },
    { ID:"3", Name:"Vegetables", Limit:5 },
    { ID:"4", Name:"Meats", Limit:2 }
];
var myViewModel = new MyViewModel(dataList);
ko.applyBindings(myViewModel);

function MyViewModel(dataList) {
    var self = this;
    self.ourTypes = ourTypes;
    self.mainArray = ko.observableArray([]);

    if (dataList.length > 0) {
        for (var i=0; i<dataList.length; i++) {
            var myDataViewModel = new MyDataViewModel(dataList[i]);
            //alert(myDataViewModel.OurType);
            self.mainArray.push(myDataViewModel);
        } 
    }
}

function MyDataViewModel(vm) {
    var self = this;
    if (vm != null) {                     
        var myType = "";
        for (var i=0; i<ourTypes.length; i++) {
            if (ourTypes[i].ID == vm.OurTypeId)
                myType = ourTypes[i].Name;
        }
        self.OurTypeId = ko.observable(vm.OurTypeId);
        self.OurType = myType;
   } else {
       self.OurTypeId = 0;    
       self.OurType = "";    
   }
   self.OurTypeId.subscribe(function(newValue) {
       var updatedItem = 0;
       var newName = "";
       for (var i=0; i<ourTypes.length; i++) {
          if (ourTypes[i].ID == newValue) {
            self.OurType = ourTypes[i].Name;
            // alert(ourTypes[i].Name);
             updatedItem = i;
          }
       }
   //  I want to do something like this to update "OurType" in mainArray...
   //  var theList = MyViewModel.mainArray();
   //  theList[updatedItem].OurType = self.OurType;
   //  MyViewModel.mainArray(theList);
   });
}

这实际上是代码的精简版本,仅关注“ourTypes”,我的 fiddle 还有更多内容。我使用下拉列表中的 ID 来指示模型中的更改,但随后我必须手动更新类型的实际名称(您将看到当 ID 在我的 fiddle 中更新时名称不会更新),所以我尝试在 .subscribe() 函数中执行此操作,但似乎没有任何效果。有什么想法吗?

fiddle :http://jsfiddle.net/navyjax2/ks6nbzp7/

最佳答案

OurType的名字起当您更改 ID 时,应该会自动更改,这对于 computed observable 来说是一项很好的工作。 :

self.OurType = ko.computed(function() {

    return ko.utils.arrayFirst(ourTypes, function(type) {
        return type.ID == self.OurTypeId();
    }).Name;

});

当计算的可观察量运行时,它会记录访问的所有其他可观察量 - 在我们的例子中,这只是 self.OurTypeId() 。这就是所谓的依赖。每当依赖项发生变化时,计算就会自动再次运行。

在这里,我们使用 Knockout 辅助函数 ko.utils.arrayFirst迭代ourTypes并返回其中 ID 与 self.OurTypeId() 匹配的第一个元素用户已选择。然后我们返回.Name其中ourType元素。

JSFiddle

请注意您的if (vm != null) else子句可能会带来麻烦:您在那里设置的值是不可观察的。

self.OurTypeId = 0;

这意味着MyDataViewModel哪里 vmnull将被打破 - knockout 将绑定(bind) <select>到一个简单的、不可观察的“0”,并且永远不会再次更新。

另外,有一次你正在制作 self.SlotPosition一个可观察的,另一次你将它设为一个可观察的数组。

最好将属性初始化为可观察一次并仅更新其值:

function MyDataViewModel(vm) {
    var self = this;

    this.SlotPosition = ko.observable();
    this.OurTypeId    = ko.observable();

    if (vm) {
        this.SlotPosition(vm.SlotPosition);
        this.OurTypeId(vm.OurTypeId);
    }

    this.OurType = ko.computed(function() {

        if (!self.OurTypeId()) {
            return;
        }

        return ko.utils.arrayFirst(ourTypes, function(type) {
            return type.ID == self.OurTypeId();
        }).Name;

    });
}

关于javascript - Knockout.js - 更新父 View 模型中的数组,并使用第二 View 模型中的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28514159/

相关文章:

javascript - 在 JavaScript 中按字符串开头或单个字符进行匹配

c - c中数组的相等性

java - 我如何修改我的程序以要求我替换数组中输入的给定数字,因为它不在所需的范围内

java - zk 如何使用 mvvm 为每个或模板生成 zul 中的组件?

c# - 探索为每个使用它的 ViewModel/Class 设置 DbContext 的陷阱(如果有的话)

javascript - 将 HTML 转换为文本,然后再转换回 HTML 以添加到页面

javascript - 如何从 jszip 和 angularjs 中的 zipobject 获取 csv 文件对象

javascript - 隐藏 tr 如果它的 td :nth-child() first letter not contains letter

php - 如何从数组中删除重复的项

c# - WPF MVVM 后台打印数据绑定(bind)问题