【问题标题】:binding nested viewmodels: knockout绑定嵌套视图模型:淘汰赛
【发布时间】:2013-06-12 17:31:37
【问题描述】:

我有嵌套的 ViewModel,MainViewModel 包含嵌套 VM 的实例。

相同的代码在这里:http://jsfiddle.net/nayanakalkur/2YCsN/19/

查看代码:

<div id="familyDiv">
    <ul data-bind="foreach: AllProductsModel">
        <li data-bind="click:function(data, event){ $('#subFamilyDiv').show(); $('#familyDiv').hide(); $root.GetSubFamilyForProducts(data, event); }">
            <a data-bind="text: productname">   
            </a>
        </li>                    
    </ul>                
</div>

 <div id="subFamilyDiv">
     <a id="btnBackToFamily" data-bind="click: function(){ $('#subFamilyDiv').addClass('hidePanel'); $('#familyDiv').removeClass('hidePanel'); }">Back</a>
     <div id="subFamilyAccProduct">
         <div data-bind="foreach: submenu">
             <ul  data-bind="text: subMenuName">
             </ul>
         </div>
     </div>
</div>

虚拟机代码:

var VM;
$(document).ready(function () {
    VM = new MainViewModel();
    ko.applyBindings(VM,document.getElementById("familyDiv"));
    ko.applyBindings(VM.productModel, document.getElementById("subFamilyAccProduct"));
    FetchProductFamiliesForProductsKO();
});

function FetchProductFamiliesForProductsKO() {
    var data=[{family: 'family1'},{family:'family2'},{family:'family3'}];

    for (var i = 0; i < data.length; i = i + 1) {
        var fam = data[i].family;
        console.log(fam);
        VM.AddProducts(fam, null, fam);
    }
};

ProductMenu= function(name, subProductsMenu1, selectedMenu) {
    var self= this;
    self.productname = ko.observable(name);
    self.submenu = ko.observableArray([]);
    self.selectedProductName = ko.observable();
};

ProductSubMenu=function() {
    var self = this;
    self.submenuName = ko.observable();
    self.submenu2 = ko.observableArray([]);
    self.selectedSubMenuName = ko.observable();
};

ProductSubMenu2= function() {
    var self = this;
    self.submenu2Name = ko.observable();
    self.properties = ko.observableArray([]);
    self.selectedSubMenu2Name = ko.observable();
};

Properties= function() {
    var self = this;
    self.pName = ko.observable();
    self.shortDesc = ko.observable();
    self.longDesc = ko.observable();
    self.additionalDocs = ko.observableArray([]);
};

function MainViewModel() {
    var self= this;
    self.productModel = new ProductMenu();
    self.subMenuModel = new ProductSubMenu();
    self.submenu2Model = new ProductSubMenu2();
    self.propertyModel = new Properties();
    self.AllProductsModel = ko.observableArray([]);

    //if true- show family products, hide sub family products 
    self.ReturnToFamilyProduct = ko.observable(true);
    self.ShowSubMenu = ko.observable(false);
    self.showSubMenu2 = ko.observable(false);
    self.ShowBackBtnOnSubMenuClick = ko.observable(false);
    self.IfDocumentsPresent = ko.observable(true);

    //to add product to products array
    self.AddProducts = function (name, subProductsMenu1, selectedMenu) {
        this.AllProductsModel.push(new ProductMenu(name, subProductsMenu1, selectedMenu));
    };

    self.GetSubFamilyForProducts = function (data, event) {
        this.ShowSubMenu = ko.observable(true);
        SubProductMenus1 = [];
        //this.ShowBackBtnOnSubMenuClick = ko.observable(true);
        var currentElement = data;
        $('#subFamilyDiv').show();
        $('#btnBackToFamily').html("back: "+currentElement.productname());
        self.productModel = new ProductMenu();
        self.productModel.productname = ko.observable(currentElement.productname());
        self.selectedProductName = ko.observable(currentElement.productname());
        var data=[{subFamily: 'subFamily1'},{subFamily:'subFamily2'},{subFamily:'subFamily3'}];

            $(data).each(function (index, subFamily) {
                var tt= data[index].subFamily;
                var temp = new ProductSubMenu();
                console.log("subfamily:"+ tt);
                temp.submenuName = tt;
                SubProductMenus1.push(temp);
            });

            self.productModel.submenu = ko.observable(SubProductMenus1);
            ko.utils.arrayForEach(self.AllProductsModel(), function (product) {
                if (product.productname() == currentElement.productname()) {
                    console.log("found"+ product.submenu().length);
                    product.submenu = ko.observable(SubProductMenus1);
                    console.log("found"+ product.submenu().length);
                }
            })

    };
}

productModel 下定义的子菜单绑定失败。

任何帮助将不胜感激。

谢谢!

【问题讨论】:

  • 你能描述一下预期结果和实际结果吗?
  • 预期结果是:在选择家庭类型时,应显示子家庭。比如:family1,family 2,family 3..在选择family1-子家庭应该出现。为此,我在 ProductMenu 构造函数中创建了一个名为 submenu 的 observableArray。子菜单成员在 GetSubFamilyForProducts 方法中填写。现在新填充的视图模型 - mainviewmodel 中的 self.productModel 绑定到了 div-
    。应该如何更改视图中的绑定,以便我可以遍历视图中的子菜单项?

标签: knockout.js


【解决方案1】:

子菜单属性不包含任何项目。在这个fiddle 中,我只是添加了一个假项目,结果视图显示了一个 fakeSubMenu 元素。所以我认为你只需要在子菜单属性中添加项目就可以了。

这就是我所做的:

ProductMenu= function(name, subProductsMenu1, selectedMenu) {
    var self= this;
    self.productname = ko.observable(name);
    self.submenu = ko.observableArray([{subMenuName: 'fakeSubMenuName'}]);
    self.selectedProductName = ko.observable();
};

希望对你有帮助。

See fiddle

【讨论】:

  • self.submenu= ko.observableArray();- 这是一个包含 ProductSubMenu 作为单个元素的数组。所以最初数组是空的。它被填写在 GetSubFamilyForProducts 函数中。你可以修改代码来做同样的事情吗?我将项目添加到 self.submenu 可观察数组。现在应该如何绑定到视图?
  • 您最好一次创建所有项目(菜单和子菜单)并具有可见的属性。然后,当您单击一个项目时,您唯一需要做的就是将 visible 属性设置为 true。我看到你重新创建了很多 observbles。这是不正确的。要设置属性,您需要这样做: self.property('newValue');而不是 self.property=ko.observable('newvalue')。第二行不会刷新视图,因为新的 observable 没有被 ko 引擎监听(它没有被绑定)。
  • 我有一大串要创建的子菜单。所以想到只在选择主菜单项时填充它们。有没有办法将新创建的 observable 绑定到视图?以便显示?
猜你喜欢
  • 2013-05-31
  • 1970-01-01
  • 2015-08-17
  • 2013-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-19
相关资源
最近更新 更多