KNOCKOUT JS observableArray重复

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了KNOCKOUT JS observableArray重复相关的知识,希望对你有一定的参考价值。

我的html页面是:

<div data-role="content">   
    <div id="menu">
        <ul id="menu" data-role="listview" class="ui-listview " 
            data-bind="foreach: menu">
            <li>
                <a data-bind="text:name, attr: {href: urlmenu}"></a>
                <a href="#"  data-bind="{ click: $parent.remove }" 
                   data-role="button" data-icon="delete"></a>
            </li>
        </ul>
     </div> 
</div>

<div data-role="footer" data-position="fixed">
    <div data-role="navbar">
        <ul id="footer">
            <li><a href="#home" data-icon="home">Home</a></li>
            <li><a href="#Asignaturas" data-icon="grid">Asignaturas</a></li>
            <li><a href="#bandejaentrada" data-icon="mail">Mensajes</a></li>
        </ul>
    </div>
</div>

我的JS代码是:

$( document ).on( "pagebeforechange" , function(e, data) {
      var toPage = data.toPage[0].id;

     if( toPage == "home"){
         ko.cleanNode(document.getElementById('menu'));
         menu();
     }
});

function menuViewModel(){
    var self = this;
    self.menu = ko.observableArray([]);
    self.menu.removeAll();
    self.menu = ko.observableArray([
                    new EditMenuViewModel("Perfil"),
                    new EditMenuViewModel("Asignaturas")
                ]);
}

function EditMenuViewModel(name) {
    this.name = ko.observable(name);
    this.urlmenu = ko.observable("#"+name);        
};    

function menu(){
    var menuviewModel = new menuViewModel();
    ko.applyBindings(menuviewModel, document.getElementById('menu'));       
}

当我第一次加载我的页面时,一切正常,但当我点击链接页脚回家时,数组内容是重复的。

示例在这里:

任何的想法?

谢谢

答案

你有两个DOM元素与id=menudivul

<div id="menu"> <!-- <-- change this id for example -->
    <ul id="menu" data-role="listview" class="ui-listview " 
        data-bind="foreach: menu">
    ...
    </ul>
</div>

ID应该是唯一的,你需要更改你的一个元素的id,希望这也将解决你的问题。

更新

正如你可以在this thread中读到的那样,ko.cleanNode不会删除使用foreach绑定创建的项目。

你需要改变你的方法。

这是一个再现你的问题的jsFiddle

您可以做的是停止清理+应用绑定,并更新您的observableArray:

$( document ).on( "pagebeforechange" , function(e, data) {
      var toPage = data.toPage[0].id;

     if( toPage == "home"){
         menuviewModel.menu.removeAll(); //clear menu
         //add whatever menu item you need
         menuviewModel.menu.push(new EditMenuViewModel("New Menu1 " + (new Date()).getTime()));
         menuviewModel.menu.push(new EditMenuViewModel("New Menu2 " + (new Date()).getTime()));
     }
});

function menuViewModel(){
    var self = this;
    self.menu = ko.observableArray([]);
    self.menu.removeAll();
    self.menu = ko.observableArray([
                    new EditMenuViewModel("Perfil"),
                    new EditMenuViewModel("Asignaturas")
                ]);
}

function EditMenuViewModel(name) {
    this.name = ko.observable(name);
    this.urlmenu = ko.observable("#"+name);        
};    

//bind only once
var menuviewModel = new menuViewModel();
ko.applyBindings(menuviewModel, document.getElementById('menu'));

这是an example

另一答案

这是旧线程,但我发现了一种(丑陋的)方法来克服它:在清理之前,我正在缓存可观察的数组值并仅使用1值设置它。重新绑定后,我正在恢复缓存的值。像这样的东西:

var self = this;
self.myArray = ko.observableArray(['val1', 'val2']);
var tempArray = [];
self.BeforeCleaning = function () {
    tempArray = self.myArray()
    self.myArray(['temp value']);
};

self.AfterRebinding = function () {
    self.myArray(tempArray);
};

可怕,但对我有用。

以上是关于KNOCKOUT JS observableArray重复的主要内容,如果未能解决你的问题,请参考以下文章

带有 knockout.js 和 ORM 的 TypeScript

更新 knockout.js 和 SignalR 库后,knockout-mapping js 不会更新视图中的列表

knockout.js - 数据绑定文本默认值

knockout.js

knockout.js

Knockout.js 和 Jquery Mobile