Angular 4:仅绑定一次返回promises的方法

时间:2017-07-04 07:58:56

标签: angular binding

我是Angular的新手,所以请原谅我,如果我不这样做,请使用正确的术语。

我试图通过将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元素中显示服务的返回值。我愿意选择另一条路来解决这个问题。一旦将数据加载到表中,就不会对其进行编辑,但我不确定单向绑定是否可以帮助我,我还不了解如何实现单向或双向绑定。

提前感谢您的协助。

1 个答案:

答案 0 :(得分:0)

找到解决方案。

首先,我绑定了一个返回promise的表达式。在这个链接Angular Docs,有角度的团队不鼓励在这里使用复杂的印象:

  

表达式可以调用getFoo()之类的东西。只有你知道getFoo()的作用。如果getFoo()改变某些东西并且你碰巧绑定了那个东西,你就会冒着不愉快的经历。 Angular可能会也可能不会显示更改的值。 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模板的代码仍然保持不变。我希望这可以帮助其他需要它的人。这更像是我原来思路的另一种选择,但如果有人有更好的方法,请随时提供帮助