【问题标题】:Nativescript RadListView input element value jumps when scrollingNativescript RadListView 输入元素值在滚动时跳跃
【发布时间】:2017-08-09 15:46:42
【问题描述】:

我正在尝试在每行/单元格中使用带有 TextField 和 TextView 的 RadListView 构建一个列表。列表正确显示,但是当列表足够长可以滚动并且我在输入字段中输入任何内容(例如“hello”并滚动时,“hello”将随机移动到不同的项目。

示例: 包含 50 行的列表。我在第 1 行的文本字段中输入“hello”。我向下滚动,使第 1 行不再可见。 “你好”出现在第 12 行的文本字段中。我滚动回第 1 行,文本字段为空。我向下滚动到第 12 行,它是空的,但“你好”现在显示在第 18 行的文本字段中……等等

代码如下:

import { Component } from "@angular/core";


class DataItem {
constructor(public id: number, public name: string) { }
}

@Component({
selector: "orderpage_rad",
template: `
<StackLayout>
<RadListView [items]="myItems">
    <ng-template tkListItemTemplate let-item="item" let-i="index">
    <StackLayout>
        <Label [text]='"index: " + i'></Label>
        <Label [text]='"name: " + item.name'></Label>
        <TextField keyboardType="number" hint="quantity"></TextField>            
        <TextView hint="enter text" editable="true"></TextView>             
    </StackLayout>
    </ng-template>                
</RadListView>
</StackLayout>
`    
})

export class orderComponent_rad {


public myItems: Array<DataItem>;
private counter: number;

constructor(){

    this.myItems = [];
    this.counter = 0;
    for (var i = 0; i < 50; i++) {
        this.myItems.push(new DataItem(i, "data item " + i));
        this.counter = i;
    }            
}

}

我使用普通的 nativescript ListView 得到了相同的结果,所以我不认为这是一个错误。

我该如何纠正这个问题?

我正在使用带有 Typescript 的 Angular,目前只在 Android 上进行测试:

tns --version: 3.1.2

跨平台模块版本:3.1.0

【问题讨论】:

    标签: angular nativescript radlistview


    【解决方案1】:

    在 Hamdi W 的帮助下,我终于找到了解决方案。所有功劳归于他。

    这里是为将来可能遇到相同问题的任何人准备的:

    import { Component, OnInit } from "@angular/core";
    import {TextField} from 'tns-core-modules/ui/text-field';
    
    class ProductItem {
     constructor(
        public id: number,
        public name: string, 
        public quantity: number
    ) { }
    }
    
    @Component({
    selector: "Home",
    moduleId: module.id,
    template: `
        <StackLayout>
            <Label text='submit' (tap)="submit()"></Label>
            <ListView [items]="products">
                <ng-template let-item="item" let-i="index">
                    <StackLayout>
                        <Label [text]='"name: " + item.name'></Label>
                        <TextField keyboardType="number"
                                   [id]='item.id'
                                   [hint]="'quantity' + i"
                                   [text]='item.quantity'
                                   (returnPress)="onReturn($event)"
                        </TextField>
                        <Label [text]='item.quantity'></Label>
                    </StackLayout>
                </ng-template>
            </ListView>
        </StackLayout>
    `
    })
    export class HomeComponent{
    public products: Array<ProductItem>;
    
    constructor(){
        this.products = [];
        for (var i = 0; i < 50; i++) {
            this.products.push(new ProductItem(i, "data item " + i, i));
        }
    }
    
    private submit()
    {
        //send to server this.products
    }
    
    public onReturn(args) {
        const {id, text} = <TextField>args.object;
    
        this.products = this.products.map(product => {
            if(product.id === parseInt(id)){
                product.quantity = parseInt(text);
            }
            return product;
        });
    }
    }
    

    解决方法是 onReturn() 函数,你可以将 (returnPress)="onReturn($event)" 改为 (textChange)="onReturn($event)"

    【讨论】:

      【解决方案2】:

      这是我找到的一个更简单的答案,我们可以使用 Nativescript 2 方式绑定获得相同的答案:

      我们删除了这个函数:(returnPress)="onReturn($event)" 和这个 [text]='item.quantity' 并替换为 [(ngModel)]="products[i].quantity"

      现在在 TextField 中所做的任何更改都会自动更新对象,并且列表视图将在需要再次渲染元素时使用新值。

      代码如下:

      import { Component, OnInit } from "@angular/core";
      import {TextField} from 'tns-core-modules/ui/text-field';
      
      class ProductItem {
      constructor(
          public id: number,
          public name: string, 
          public quantity: number
      ) { }
      }
      
      @Component({
      selector: "orderpage_rad",
      moduleId: module.id,
      template: `
          <StackLayout>
              <Label text='submit' (tap)="submit()"></Label>
              <ListView [items]="products">
                  <ng-template let-item="item" let-i="index">
                      <StackLayout>
                          <Label [text]='"name: " + item.name'></Label>
                          <TextField keyboardType="number"
                                     [id]='item.id'
                                     [hint]="'quantity' + i"
                                     [(ngModel)]="products[i].quantity">
                          </TextField>
                          <Label [text]='item.quantity'></Label>
                      </StackLayout>
                  </ng-template>
              </ListView>
          </StackLayout>
       `
      })
      export class orderComponent_rad{
      public products: Array<ProductItem>;
      
      constructor(){
          this.products = [];
          for (var i = 0; i < 50; i++) {
              this.products.push(new ProductItem(i, "data item " + i, i));
          }
      }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2015-02-27
        • 2015-05-06
        • 1970-01-01
        • 2014-10-23
        • 1970-01-01
        • 1970-01-01
        • 2017-07-01
        • 1970-01-01
        • 2013-01-25
        相关资源
        最近更新 更多