2016-08-18 76 views
0

我有一個警報系統,用戶需要能夠創建無限數量的警報,併爲每個警報添加無限數量的觸發器。將新對象添加到陣列時出現角度陣列重複錯誤

例如,用戶可能會有一個名爲「當我的汽車價格變化時」的警報。他們需要能夠爲他們想要遵循的每輛車創建相同類型的觸發器(「價格變化」)。

接下來是一個精簡版,只處理觸發器。

​​- 只需按兩次Add即可看到問題。

JS

// the array of trigger possibilities 
$scope.triggerOptions = [ 
    {id : 0, type: 1, action: "Status Update For Brand"}, 
    {id : 1, type: 2, action: "Price Changed for "} 
]; 

// the model for the select element 
$scope.selected = $scope.triggerOptions[0]; 

// this array will hold all the triggers created 
$scope.triggers = []; 

// add some indexes to the new trigger object, then add it to triggers 
$scope.addTrigger = function() { 
    var newTrigger = $scope.selected; 
    var newID = $scope.triggers.length; 
    var alertID = 0; // todo: apply alert id 
    newTrigger.triggerID = newID; 
    newTrigger.alertID = alertID; 
    $scope.triggers.push(newTrigger); 
}; 

HTML

<select ng-options = "option.action for option in triggerOptions track by option.id" ng-model = "selected"></select> 
<button ng-click="addTrigger()">Add</button> 

<div ng-repeat="trigger in triggers track by triggerID" class="alert-tool-action-box"> 
    <div ng-show="trigger.type==1"> 
    <div>{{trigger.action}}</div> 
    </div> 

    <div ng-show="trigger.type==2"> 
    <div>{{trigger.action}}</div> 
    </div> 
</div> 

問題

  • 當我添加多個觸發器,只顯示第一個觸發器,但我得到一個「傻瓜」error message(這表明我添加了'追蹤',但我已經這樣做了)。
  • 當我連續添加兩個相同類型的觸發器,該triggerID更新爲新triggerID兩個觸發器:

一個觸發器:

[{"id":0,"type":1,"action":"Status Update For Brand","triggerID":0,"alertID":0}] 

兩個觸發器:

[ 
    {"id":0,"type":1,"action":"Status Update For Brand","triggerID":1,"alertID":0}, 
    {"id":0,"type":1,"action":"Status Update For Brand","triggerID":1,"alertID":0} 
] 

我應該可以在添加它們時看到每個觸發器,即使它們與之前的相同。

+0

TL; DR; 'track by'必須是唯一的,所以'triggerID'不能包含愚蠢。你總是可以用'$ index'來試試和追蹤。 –

+1

或者根本不使用軌道。但爲什麼你首先有兩個具有相同ID的觸發器?不是一個ID應該唯一標識一個觸發器? –

回答

1
  • 你NG重複只顯示一個您陣列的representant因爲你通過triggerID跟蹤不存在(角應搜索它在$範圍和不確定的每一次它稱之爲返回)。調用triggerID的好方法是trigger.triggerID。所以:

    <div ng-repeat="trigger in triggers" class="alert-tool-action-box"> 
        .... 
    </div> 
    

    ,或者如果你想使用的軌道:

    <div ng-repeat="trigger in triggers track by trigger.triggerID class="alert-tool-action-box"> 
        .... 
    </div> 
    
  • 你的第二個問題是鏈接到一個事實,即JavaScript的通對象通過引用而不是值。你不創建一個新的對象。你只是通過相同的方式並改變它的價值。這就是爲什麼你的所有對象都使用相同的ID進行更新。 所以你可以使用angular.copy()來使它不同的對象。喜歡的東西:

    $scope.addTrigger = function() { 
        var newTrigger = angular.copy($scope.selected); 
        var newID = $scope.triggers.length; 
        var alertID = 0; // todo: apply alert id 
        newTrigger.triggerID = newID; 
        newTrigger.alertID = alertID; 
        $scope.triggers.push(newTrigger); 
    }; 
    
+0

噢,好的。我想通過將'selected'分配給一個新變量,它創建了一個新實例。謝謝! –

+0

對於主要價值,是的。不是爲了客體。 –

+0

好的,我從'ng-repeat'中刪除了'track by',儘管我不明白你的解釋,爲什麼這個工作和triggerID跟蹤沒有 - triggerID需要是唯一的 - 它們不是唯一的嗎? –

2

您的對象數組不能包含重複項(錯誤:[ngRepeat:dupes]),現在這兩個對象是相等的。這可以使用track by來解決,它必須是唯一的,所以triggerID不能在這裏使用。如果沒有可用的唯一屬性,則始終可以使用track by $index(由ng-repeat指令提供)。

+0

triggerID被設置爲觸發器數組的長度,所以它不會是唯一的,對吧?我的意思是每次添加對象時,該數字都會改變。但是感謝'$ index'的想法,我會嘗試一下。 –

2

關於你的第二個問題,你總是把相同的對象,因爲你只有$範圍的1個實例。 爲了解決這個問題,你只需要克隆(或複製)$ scope.selected,像這樣:

var newTrigger = angular.copy($scope.selected);

希望它能幫助!

+0

解決了設置triggerID的問題,但仍然只有一個觸發器出現,即使觸發器對象中有很多觸發器。 https://plnkr.co/edit/yn6t8PHN1QRXOzy4uv7q?p=preview –