4

Я столкнулся с странным поведением, связанным с ng-init, любая помощь будет оценена.ng-init просчитывает индекс псевдонимов после array.splice

У меня есть объект модели, который имеет свойство квартир, которое представляет собой массив плоских объектов. Каждый плоский объект имеет свойство помещений, которое представляет собой массив предметов комнаты.

Я пытаюсь показать квартиру и комнаты следующим образом;

<table ng-repeat="flat in model.flats" ng-init="flatIndex = $index"> 
<thead> 
<tr> 
    <td>{{flatIndex+1}}. {{flat.name}}</td> 
</tr> 
</thead> 
<tbody> 
<tr ng-repeat="room in flat.rooms" ng-init="roomIndex = $index"> 
    <td>{{roomIndex+1}}. {{room.name}}</td> 
</tr> 
</tbody> 
</table> 

Если я удалить квартиру или комнату с помощью array.spliceflatIndex и roomIndex переменные, кажется, не правильно обновить даже хотя $index и пользовательский интерфейс обновления правильно.

Вы можете увидеть эту проблему here в действии.

Попробуйте удалить 1-й, 2-й или 3-й квартирный или комнатный объект, нажав ссылку удаления. Удаление последнего объекта из массива на самом деле не вызывает проблемы.

Любые обходные пути также будут оценены.

ответ

2

Это известное поведение при использовании ng-init, значения свойств области, заданные в ng-init, не просматриваются, и они не обновляются при удалении элементов из массива, чтобы отразить обновленную позицию индекса. Поэтому не используйте ng-init, а просто используйте $index (deleteFlat($index)) и flat ссылку на объект (чтобы попасть в комнаты deleteRoom(flat,$index)).

<table ng-repeat="flat in model.flats track by flat.id"> 
<thead> 
    <tr> 
     <td colspan="2">{{$index+1}}. {{flat.name}}</td> 
     <td><a href="#" ng-click="deleteFlat($index)">DELETE FLAT</a></td> 
    </tr> 
</thead> 
<tbody> 
    <tr ng-repeat="room in flat.rooms track by room.id"> 
     <td>&nbsp;</td> 
     <td>{{$index+1}}. {{room.name}}</td> 
     <td><a href="#" ng-click="deleteRoom(flat,$index)">DELETE ROOM</a></td> 
    </tr> 
</tbody> 
</table> 

и

$scope.deleteFlat = function(flatIndex){ 
    $scope.model.flats.splice(flatIndex,1); 
}; 

$scope.deleteRoom = function(flat,roomIndex){ 
    flat.rooms.splice(roomIndex,1); 
}; 

Plnkr

Или лучше использовать сам, deleteFlat(flat.id) и deleteRoom(room.id, flat) идентификаторами.

<table ng-repeat="flat in model.flats track by flat.id"> 
<thead> 
    <tr> 
     <td colspan="2">{{$index + 1}}. {{flat.name}}</td> 
     <td><a href="#" ng-click="deleteFlat(flat.id)">DELETE FLAT</a></td> 
    </tr> 
</thead> 
<tbody> 
    <tr ng-repeat="room in flat.rooms track by room.id"> 
     <td>&nbsp;</td> 
     <td>{{$index+1}}. {{room.name}}</td> 
     <td><a href="#" ng-click="deleteRoom(room.id, flat)">DELETE ROOM</a></td> 
    </tr> 
</tbody> 
</table> 

и

$scope.deleteFlat = function(flatId){ 
    $scope.model.flats.splice(_getItemIndex(flatId, $scope.model.flats), 1); 
}; 

$scope.deleteRoom = function(roomId, flat){ 
    flat.rooms.splice(_getItemIndex(roomId, flat.rooms), 1); 
}; 


function _getItemIndex(imtId, itms){ 
    var id ; 
    itms.some(function(itm, idx){ 
     return (itm.id === imtId) && (id = idx) 
    }); 
    return id; 
} 

Plnkr2

+0

** [Здесь прокладка для array.some для старых браузеров] (https://developer.mozilla.org/en-US/ docs/Web/JavaScript/Reference/Global_Objects/Array/some) ** Вы можете просто использовать цикл for. – PSL

+0

Я не знал, что переменные ng-init не просматриваются. Но я должен был догадаться, что :) спасибо за ответ. веселит. – ysf

+1

@ysf Добро пожаловать. :). Не только это, вы также можете столкнуться с подобными проблемами при использовании фильтров. Поэтому лучше постарайтесь не полагаться на '$ index', особенно когда у вас есть идентификатор .. :) – PSL

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