2013-03-12 2 views
2

Я использую KnockoutJS и имею многомерный массив наблюдаемого объекта (?):Удаления элемента из массива многомерного Javascript, основанные на стоимости недвижимости

self.navItems = ko.observableArray([ 
    { name: "test1", children: [ 
     { name: "test1child1", children: [] }, 
     { name: "test1child2", children: [] } 
    ]}, 
    { name: "test2", children: [] }, 
]); 

Я хотел бы, чтобы иметь возможность удалить один из объекты, основанные на значении свойства. В других работах, я хотел бы сделать что-то это:

removeNavItem("test1child2"); 

Я написал функцию, но не могу заставить его работать, потому что он ищет «test1child2» как свойство, а не стоимость.

self.removeNavItem = function (itemName) { 
    var item = ko.utils.arrayFirst(self.navItems(), function (item) { 
     if (item.name === itemName) { // this seems to work correctly 
      delete self.navItems[itemName]; // this doesn't, because it tests property, not value 
     } 
    }); 
}; 

jsfiddle link

EDIT:

Я не знал о встроенных в отдалении/RemoveAll методов нокаутов.

Благодаря комментариям ниже, я частично работаю, но когда я пытаюсь удалить что-то внутри детей [], он также удаляет весь родитель.

removeNavItem = function (itemName) { 
    var items = self.navItems.remove(function (item) { 
     for (i = 0; i < item.children.length; i++) { 
      if (item.children[i].name === itemName) { 
       return item.children[i].name; 
      } 
     } 
     return item.name === itemName; 
    }); 
}; 

updated jsfiddle

ответ

1

Если вы хотите, чтобы иметь возможность использовать его на любом уровне, а затем передать в массив, который вы хотите, чтобы удалить его из:

self.removeNavItem = function (obsArray, itemName) 
{ 
    obsArray.remove(function(item) { return item.name === itemName }); 
}; 

Тогда вы можете назвать это на каждом элементе:

click: function() { $root.removeNavItem($parent.children, $data.name); } 

Я обновил свой jsfiddle, и она работает, Тхо вам нужно сделать все дочерние массивы наблюдаемыми массивами, чтобы они работали.

+0

Спасибо! 1 проблема у меня с этим, что она работает для элементов верхнего уровня, но не для второго или третьего уровня. – dmathisen

+0

Вы имеете в виду массив детей в вашем коде? –

+0

Да, точно. Я думаю, что я смогу использовать if (item.children.length> 0) {...} перед возвратом, чтобы заставить его работать. Я поиграю с этим. – dmathisen

1

Существует более простой способ сделать это. Нокаут обеспечивает remove(), который может использовать функцию для удаления элементов соответствия:

self.removeNavItem = function (itemName) { 
    var items = self.navItems.remove(function (item) { 
     return item.name === itemName; 
    }); 
}; 

(Это упоминается в «Удалить и RemoveAll» раздел в observableArrays documentation)

1

Я думаю, вам будет нужна функция, которая сделает поиск по п уровня рекурсии

function del(obj,val){ 
    $.each(obj,function(i,j){ 
     if(j['name'] == val){ 
      delete(j); 
      return false; 
     }else if(j['children'].length!=0){ 
      del(j['children'],val); 
     } 
    }) 

} 

этой функции два аргумента вашего объекта и значение для поиска, вы можете изменить его в соответствии с вашим делом.

Смежные вопросы