2017-07-04 57 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模板的代码仍然保持不变。我希望这可以帮助需要它的其他人。这更像是我的原始思路的另一种选择,但如果有人有更好的方式去做,请随时协助