2017-07-04 105 views
0

我是Angular的新手,所以請原諒我,不要使用正確的術語。角度4:綁定一次只能返回承諾的方法

我想通過將td數據綁定到方法調用來動態創建表。像這樣:

<tbody> 
    <tr *ngFor="let rw of ParameterRowData" > 
    <td *ngFor="let field of fields" class="lalign" [innerHTML]="getCellData(field, rw.ParameterData)" ></td> 
    <td><a >Edit</a> </td> 
    </tr> 
</tbody> 

我這樣做是因爲我不知道可用的列和數據,直到它從服務器返回。我的問題是getCellData方法一遍又一遍地被調用。瀏覽器凍結,但在控制檯中,我可以看到它被一次又一次地調用到無窮大。我只希望它被調用一次。

的getCellData方法如下:

getCellData(field: ParamField, fields : ParameterRowFieldContract[]) : Promise<string> 
    { 
     for(var i=0; i<fields.length; i++) 
     {   
      if(fields[i].Name===field.DisplayName) 
      { 
       console.log('a'); 
       if(field.DataType == "FOREIGNKEYLIST") 
       { 
        //getforeign key value to display 
        console.log('b'); 
        var value = this.paramService.getParameterDataWithId(field.ForeignParameter, fields[i].Value) 
        .then(para => {  
         for(var k=0; k<para.ParameterData.length; k++) 
         { 
          console.log('c'); 
          if(para.ParameterData[k].Name===field.ForeignField) 
          { 
           console.log('foreign ='+ para.ParameterData[k].Value); 
           return para.ParameterData[k].Value; 
          } 
         } 
        }); 
        return value; 

       } 
       else 
       {    
        return Promise.resolve(fields[i].Value); 
       } 
      }  
     } 
    } 

在這一天我只是想顯示從HTML TD元素的服務返回的值的末尾。我願意選擇一條替代路線來解決這個問題。一旦將數據加載到表中,數據將不會被編輯,但我不確定單向綁定是否可以幫助我,而我還不知道如何實現單向或雙向綁定。

非常感謝您的幫助。

+0

您需要在構建此類應用程序之前充分了解角度概念。 –

+0

這是真的。但我已經陷入了深淵。這是我留下深刻印象的機會,所以不要選擇。 – peterpie

+0

也許一個自定義角管本來可以是一個更簡單的解決方案?像這個問題中的最後一個解決方案:[stackoverflow question](https://stackoverflow.com/questions/34363161/angular-2-displaying-async-object-data-from-promise) – peterpie

回答

0

找到了解決方法。

首先我綁定了一個返回promise的表達式。在此鏈接Angular Docs,角度團隊不鼓勵在這裏使用複雜的外觀:

該表達式可能會調用類似getFoo()的東西。只有你知道getFoo()是做什麼的。如果getFoo()改變了某些東西,並且碰巧遇到了這種情況,那麼就會冒着不愉快的體驗。角度可能顯示或不顯示更改的值。 Angular可能檢測到更改併發出警告錯誤。一般來說,堅持數據屬性和返回值並不再做的方法。

所以爲了保持簡單,我的方法必須返回一個字符串。

至於外國數據,我在ngOnInit上預取它並將其存儲在一個多維(2D)數組中,外國人。

foreigners = []; 
foreignParamNames : string[]; 

然後在ngOnInit中填入數據。 foreignParamNames用於跟蹤多維數組的索引。

ngOnInit() { 
this.foreigners = []; 
this.foreignParamNames = []; 
this.fields = this.param.Fields; 
this.paramService.getParameterData(this.parameterName) 
       .then(
        data => this.processData(data), 
        error => {console.log(error)}); 

var foren = this.fields.filter(a=> a.DataType == 'FOREIGNKEYLIST'); 
for(var i = 0; i< foren.length; i++) 
{ 
    this.foreignParamNames.push(foren[i].DisplayName); 
    this.foreigners.push([]); 
} 

for(var j =0; j< foren.length; j++) 
{ 
    var that = this; 
    var ogfield = foren[j]; 
    //get foreign field data 
    this.paramService.getParameterData(foren[j].ForeignParameter) 
       .then(
        foreignRows => { 
         var values : StringKeyValuePair[] 
         values =[]; 
         for(var i=0; i<foreignRows.length; i++) 
         { 
          var foreignFields = foreignRows[i].ParameterData; 
          var sk = new StringKeyValuePair(); 
          for(var j =0; j<foreignFields.length; j++) 
          { 
           if(foreignFields[j].Name=="Id") 
           { 
            sk.Key = foreignFields[j].Value; 
           } 
           if(foreignFields[j].Name==ogfield.ForeignField) 
           { 
            sk.Value = foreignFields[j].Value; 
           }   
          } 
          values.push(sk); 
         } 
         var ii = that.foreignParamNames.indexOf(ogfield.DisplayName); 
         if(ii>=0) 
         { 
          that.foreigners[ii]=(values); 
         } 
        }, 
        error => {console.log(error)}); 
    } 
} 

,然後最後,getCellData方法不再需要從服務獲取,但現在可以從多維陣列,用於它的數據獲取。這是代碼。

getCellData(field: ParamField, fields : ParameterRowFieldContract[]) : 
string 
{ 
    for(var i=0; i<fields.length; i++) 
    {   
     if(fields[i].Name==field.DisplayName) 
     { 

      if(field.DataType == "FOREIGNKEYLIST") 
      { 
       //getforeign key value to display     
       var ii = this.foreignParamNames.indexOf(field.DisplayName); 

       var foreignfields= <StringKeyValuePair[]>this.foreigners[ii]; 

       for(var k=0; k<foreignfields.length; k++) 
       { 
        if(foreignfields[k].Key===fields[i].Value) 
        { 
         return foreignfields[k].Value; 
        } 
       } 

      } 
      else 
      {    
       return fields[i].Value; 
      } 
     }  
    } 
    return "N/A"; 
    } 

HTML模板的代碼仍然保持不變。我希望這可以幫助需要它的其他人。這更像是我的原始思路的另一種選擇,但如果有人有更好的方式去做,請隨時協助