首页 > 解决方案 > 当 viewmodel 值发生变化时,如何更新列表视图?

问题描述

我是 NS 的新手,需要一些帮助才能得到一些东西,这应该很简单,可以工作。

我正在玩的应用程序只是一个简单的计时系统:当应用程序启动并点击 UI 上的刷新按钮时,它会从 API 下载(使用 fetch)一个警报列表(这只是一个数组'秒' 开始倒计时)。

下载列表后,我将视图模型中的一个变量分配给我刚刚收到的数据。我有一个绑定到这个变量的列表视图。

每秒我使用计时器将视图模型中的所有值减 1。

我的问题是列表视图似乎不会随着我对其数据源所做的更改自动更新,计时器每秒处理一次。

我假设如果我将列表视图绑定到视图模型中的一个值(警报/秒数组),那么每当我更新它的任何绑定元素时(在这种情况下,当计时器减少每个警报的值时),视图都会改变。

事实并非如此。最初填充列表视图后,它只是静态的,但计时器肯定在工作。

const ObservableArray = require("data/observable-array").ObservableArray;

const observableModule = require("data/observable");

const dialogsModule = require("ui/dialogs");

function AlarmsViewModel() {

    const viewModel = observableModule.fromObject({

        alarms: [],

        intervalId: null,

        refreshData() {

            this.alarms = [];

            if (this.intervalId) {

                clearInterval(this.intervalId);

            }

            fetch(`http://localhost:3000/alarms`).then((response) => response.json()).then((res) => {

                const alarms = res.alarms;

                this.alarms = new ObservableArray(alarms);

                this.intervalId = setInterval(() => {

                    this.alarms.forEach((alarm) => {

                        alarm--;

                    });

                }, 1000);

            }).catch(() => {

                dialogsModule.alert({

                    title: "Oops!",

                    message: "An error occured connecting to the API.",

                    okButtonText: "Got it!"

                });

            });

        }

    });

    return viewModel;
}

module.exports = AlarmsViewModel;

警报.xml

    <ActionBar title="Alarms" class="action-bar">

    </ActionBar>

    <StackLayout>

        <Button text="Refresh" tap="{{ refreshData }}" />

        <ListView items="{{ alarms }}">

            <ListView.itemTemplate>

                    <Label text="{{ $value }}" class="ends-in"/>

            </ListView.itemTemplate>

        </ListView>

    </StackLayout>

</Page>

也就是说,每秒钟,listview 元素都会根据其基础数据源中所做的更改而更改。

标签: listviewtimernativescriptcountdown

解决方案


如果要在 ListView 中绑定数组更改,请注意以下几点,

  1. 您在和之间翻转alarms变量。您必须将其保留为始终,以便可以捕获任何索引上的更改。ArrayObservableArrayObservableArray
  2. splice如果要替换特定索引中的值,则必须使用ObservableArray.

这是一个游乐场样本


推荐阅读