2016-11-02 105 views
0

我試圖編寫一些代碼來檢測角度中複雜的嵌套層次對象的更改。我希望$watch$watchCollection表達式就足夠了,但這很難實現。觀察角度的複雜對象層次結構的深度和內容

有人可以提出一個好的方法來解決這個問題嗎?

數據結構我期待看的一個例子是(以JSON):

{ 
    "$type":"<>f__AnonymousType7`2[[System.String, mscorlib],[System.Object, mscorlib]], VM.ConfigurationServer", 
    "Name":"DevelopmentEnvironment", 
    "Descendents":{ 
     "$type":"<>f__AnonymousType7`2[[System.String, mscorlib],[System.Object, mscorlib]][], VM.ConfigurationServer", 
     "$values":[{ 
      "$type":"<>f__AnonymousType7`2[[System.String, mscorlib],[System.Object, mscorlib]], VM.ConfigurationServer", 
      "Name":"MoreSpecificEnvironment", 
      "Descendents":{ 
       "$type":"<>f__AnonymousType7`2[[System.String, mscorlib],[System.Object, mscorlib]][], VM.ConfigurationServer", 
       "$values":[{ 
        "$type":"<>f__AnonymousType7`2[[System.String, mscorlib],[System.Object, mscorlib]], VM.ConfigurationServer", 
        "Name":"level3", 
        "Descendents":null 
       }] 
      } 
     }] 
    } 
} 

正如你所看到的JSON序列的TypeNameHandling設置爲所有,這是必要的其他地區系統。

我需要知道的是對任何嵌套對象的Name屬性所做的任何更改,還可以添加或刪除Descendent

我曾經嘗試都

scope.$watch(<objectname>, function(){...}, true);

scope.watchCollection(<objectname>, function(){...}, true);

這兩者的檢測對頂級NameDescendents性質,但沒有進一步的嵌套對象。

基於我的理解,這表明angular.equals函數並沒有注意到頂層以下的變化。

有沒有辦法注入自定義的相等比較器?

有沒有辦法動態更改watchExpression?因此,應用手錶中的每個對象的層次結構,並作爲層次結構的變化而變化的watchExpression

回答

1

的問題是,angular.equals()忽略鍵開始用$標誌,即你的情況$type$values比較過程中被忽略。

除Angulars自己的服務/指令等之外,不要在您的Angular代碼中使用以$ signs開頭的屬性!

Check out this fiddle並嘗試將$values數組重命名爲values

+0

鑑於該數據由的WebAPI的服務器提供的是有一個簡單的方法來更改屬性的名稱,當數據到達(與修訂前改回已發佈到服務器) – MikeW

+1

非常感謝@邁克爾 - 玫瑰,這曾經工作過,我添加了一個服務來更改基於替換數組的屬性名稱:請參閱我的'答案'(沒有足夠的空間來發布服務作爲評論) – MikeW

1

除了來自@邁克爾 - 羅斯的答案,我補充說,從轉換的WebAPI在收到數據的服務:

var DataClenseService = function() { 
"use strict"; 
this.renameFields = function (data, fieldRenames) { 
    if (data == null) { 
     return null; 
    } 

    if (typeof data !== 'object') { 
     return data; 
    } 
    var service = this; 
    Object.keys(data).forEach(function (propertyName) { 
     var matchingRenames = fieldRenames.filter(function (rename) { return rename.old === propertyName; }); 
     var currentValue = data[propertyName]; 
     if (matchingRenames.length == 1) { 
      delete data[propertyName]; 
      data[matchingRenames[0].new] = service.renameFields(currentValue, fieldRenames); 
     } else { 
      data[propertyName] = service.renameFields(currentValue, fieldRenames); 
     } 
    }); 
    return data; 
}; 

};

,只是稱這個爲這樣:

var cleanedData = DataClenseService.renameFields(data, [{ old: '$values', new: 'values' }, { old: '$type', new: 'type' }]);