首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >NativeScript --如何使用SearchBar过滤可观察到的数组?

NativeScript --如何使用SearchBar过滤可观察到的数组?
EN

Stack Overflow用户
提问于 2016-03-15 07:41:26
回答 2查看 3.9K关注 0票数 2

嗨,我正在尝试过滤一个可观察到的数据数组,该数组是通过SearchBar按键上的HTTP请求获取的。

我设法使SearchBar属性更改正常工作,但我似乎不知道自己在过滤逻辑中做错了什么。

理想情况下,我希望在SearchBar中键入搜索项时更新列表。我在Telerik网站上搜索了API,但我并没有找到任何例子。

XML

代码语言:javascript
运行
复制
<Page loaded="pageLoaded">
    <ActivityIndicator busy="{{ isLoading }}" />
    <ActionBar title="People">
    </ActionBar>
    <GridLayout>
        <StackLayout>
            <SearchBar id="searchBar" hint="Search for someone"></SearchBar>
            <ListView items="{{ peopleList }}" itemTap="showDetail">
                <ListView.itemTemplate>
                    <StackLayout>
                        <Label text="{{ fullName }}" horiztonalAlignment="left" verticalAlignment="center"></Label>
                        <Label text="{{ company }}" class="info"></Label>
                    </StackLayout>
                </ListView.itemTemplate>
            </ListView>
        </StackLayout>
    </GridLayout>
</Page>

JS

代码语言:javascript
运行
复制
var frames = require("ui/frame");
var Observable = require("data/observable").Observable;
var PeopleListViewModel = require("../../shared/people-viewModel");
var activityIndicatorModule = require("ui/activity-indicator");

var page;
var userkey;

var peopleList = new PeopleListViewModel([]);
var pageData = new Observable({ peopleList: peopleList });

exports.pageLoaded = function(args) {
    page = args.object;
    page.bindingContext = pageData;
    userkey = userkey || page.navigationContext.userkey;

    peopleList.load(userkey); // fetch data from the backend

    var searchBar = page.getViewById("searchBar");
    searchBar.on("propertyChange", function (args) {
        var searchText = args.object.text;
        if (searchText === "") {
            // NOT SURE WHAT TO DO HERE.
        } else {
            peopleList.filter(function (element, index, array) {
                // DOESN"T WORK PROPERLY
                console.log("element: ", JSON.stringify(element));
                return element.fullName == searchText;
            });
            console.log("Text types: ", searchText);
        }
    });
};

exports.showDetail = function(args) {
    var person = peopleList.getItem(args.index);
    var navigateEntry = {
        moduleName: "views/people/people-detail",
        context: { person: person },
        animated: false
    };
    frames.topmost().navigate(navigateEntry);
};

PeopleListViewModel.js

代码语言:javascript
运行
复制
var config = require("./config");
var fetchModule = require("fetch");
var ObservableArray = require("data/observable-array").ObservableArray;

function PeopleListViewModel(people) {
    var viewModel = new ObservableArray(people);

    viewModel.load = function (userKey) {

        return fetchModule.fetch(config.baseUrl + "/api/people/all/" + userKey)
            .then(function (response) {
                return response.json();
            })
            .then(function (data) {
                data.forEach(function (person) {
                    viewModel.push(person);
                });
            }, function (error) {
                console.log("Error: ", error);
            });
    };

    viewModel.empty = function () {
        while (viewModel.length) {
            viewModel.pop();
        }
    };

    return viewModel;
}

function handleErrors(response) {
    if (!response.ok) {
        console.log("Error occurred");
    }
}

module.exports = PeopleListViewModel;

更新的人物-名单

代码语言:javascript
运行
复制
var frames = require("ui/frame");
var Observable = require("data/observable").Observable;
var ObservableArray = require("data/observable-array").ObservableArray;
var PeopleListViewModel = require("../../shared/people-viewModel");
var activityIndicatorModule = require("ui/activity-indicator");

var page;
var userkey;

var peopleList = new PeopleListViewModel([]);
var pageData = new Observable({ peopleList: peopleList });
var resultList = new ObservableArray([]);

exports.pageLoaded = function(args) {
    page = args.object;
    page.bindingContext = pageData;
    userkey = userkey || page.navigationContext.userkey;

    peopleList.load(userkey);

    var searchBar = page.getViewById("searchBar");
    searchBar.on("propertyChange", function (args) {
        var searchText = args.object.text;

        if (searchText === "") {

        } else {

            while (resultList.length > 0) {
                resultList.pop();
            }   

            peopleList.forEach(function (element) {
                if (element.fullName === searchText) {
                    resultList.push(element);
                }
            });
        }   
    });

};
EN

回答 2

Stack Overflow用户

发布于 2016-04-27 23:01:03

我也有过同样的问题。如果要在搜索栏中的每个字符更改后筛选数据,可以尝试我的解决方案。

定义我的playerList是你的peopleList。这是来自视图模型的数据。resultList是一个数据将被推送的数组。

代码语言:javascript
运行
复制
var observableArrayModule = require("data/observable-array").ObservableArray;
var playerList = new PlayerListViewModel([]);
var resultList = new observableArrayModule([]);

var pageData = new observableModule.Observable({
  resultList: resultList,
  player: ""
});

Inside expors.loaded()

代码语言:javascript
运行
复制
  page = args.object;
  searchBar = page.getViewById("search-bar");
  page.bindingContext = pageData;

加载初始数据-在expors.loaded()中

当用户第一次导航到屏幕时,我们正在加载初始数据。我们还将相同的数据推送到resultList,因为我们在xml中使用{resultList}。可以在列表填充时添加loadingIndicator。

代码语言:javascript
运行
复制
playerList
.load()
.then(function() {
  setTimeout(function() {
    playerList.forEach(function (element) {
      pageData.resultList.push(element);
    });
  }, 1000);
})
.catch(function(error) {
  dialogsModule.alert({
    message: "An error occurred while loading players.",
    okButtonText: "OK"
  });
});

清除自动对焦-内部expors.loaded()

这是为了防止键盘打开的初始屏幕导航。

代码语言:javascript
运行
复制
  if (searchBar.ios) {
    searchBar.ios.endEditing(true);
  } else if (searchBar.android) {
      searchBar.android.clearFocus();
  }

当字符发生变化时搜索数据-在expors.loaded()中

我正在调用过滤器功能。Lodash _.debounce函数用于延迟resultList阵列的循环。没有它,每次输入字母时,应用程序都会循环运行。现在,我们正在等待用户停止键入以开始循环。

代码语言:javascript
运行
复制
searchBar.on('propertyChange', _.debounce(searchList, 500));

searchList函数

这是实际的循环。您可以根据需要更改element.name。

代码语言:javascript
运行
复制
function searchList(args) {
  var searchText = args.object.text;
  while(resultList.length > 0) {
    resultList.pop();
  }
  playerList.forEach(function (element) {
    if (element.name.toLowerCase().indexOf(searchText) >= 0) {
      resultList.push(element);
    }
  });
}

如果清除搜索栏,隐藏键盘-在exports.loaded()中

最后,如果用户清除搜索栏,我们希望隐藏键盘。

代码语言:javascript
运行
复制
searchBar.on(searchBarModule.SearchBar.clearEvent, function (args) {
  setTimeout(function() {
    searchBar.dismissSoftInput();
  }, 10);
});

PS

你可能解决了你的问题,但这可能会对未来的其他人有所帮助。

票数 6
EN

Stack Overflow用户

发布于 2016-03-15 14:53:55

好的,你的问题是Javascript问题,而不是NativeScript问题。为了解决这个问题,可以观察到的数组仅仅是普通的数组。

在JS中,您正在创建一个新的PeopleListViewModel,然后通过pageData对象附加到bindingContext。到目前一切尚好。然后调用PeopleListViewModel上的PeopleListViewModel方法(它返回一个承诺,除了这个特定的问题之外,您并没有真正做任何事情)。

然而,当输入文本时,您并没有真正做任何事情。这是你的代码:

代码语言:javascript
运行
复制
        peopleList.filter(function (element, index, array) {
            // DOESN"T WORK PROPERLY
            console.log("element: ", JSON.stringify(element));
            return element.fullName == searchText;
        });

peopleListPeopleListViewModel的一个实例,它返回一个ObservableArray。ObservableArray确实有一个名为filter的方法(它的工作原理与常规数组的筛选器一样)。查看NativeScript文档Javascript文档 of filter)。

这里您需要理解的是,filter 返回一个新的数组,其中包含过滤的结果。执行peopleList.filter()将将新数组发送到空空间。你想要var yourNewFilteredArray = peopleList.filter()。但是,您并不真的想重新定义绑定到绑定上下文的数组,而是要修改它的内容。

下面是一个如何做到这一点的例子:

代码语言:javascript
运行
复制
/*
 * Attach a new obsersable array to the binding context.
 * you can prepopulate it with the data from the 
 * PeopleListViewModel if you want to
 */
var resultList = new ObservableArray([]);
var pageData = new Observable({ resultList: resultList });

/*
 * Then on search/filter you want to modify this new
 * array. Here I first remove every item in it and then
 * push matching items to it.
 */
searchBar.on("propertyChange", function (args) {
    var searchText = args.object.text;
    // ...

    while(resultList.length > 0) {
        resultList.pop();
    }

    peopleList.forEach(function (element) {
        if (element.fullName === searchText) {
            resultList.push(element);
        }
    });
});
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36005172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档