嗨,我正在尝试过滤一个可观察到的数据数组,该数组是通过SearchBar按键上的HTTP请求获取的。
我设法使SearchBar属性更改正常工作,但我似乎不知道自己在过滤逻辑中做错了什么。
理想情况下,我希望在SearchBar中键入搜索项时更新列表。我在Telerik网站上搜索了API,但我并没有找到任何例子。
XML
<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
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
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;更新的人物-名单
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);
}
});
}
});
};发布于 2016-04-27 23:01:03
我也有过同样的问题。如果要在搜索栏中的每个字符更改后筛选数据,可以尝试我的解决方案。
定义我的playerList是你的peopleList。这是来自视图模型的数据。resultList是一个数据将被推送的数组。
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()
page = args.object;
searchBar = page.getViewById("search-bar");
page.bindingContext = pageData;加载初始数据-在expors.loaded()中
当用户第一次导航到屏幕时,我们正在加载初始数据。我们还将相同的数据推送到resultList,因为我们在xml中使用{resultList}。可以在列表填充时添加loadingIndicator。
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()
这是为了防止键盘打开的初始屏幕导航。
if (searchBar.ios) {
searchBar.ios.endEditing(true);
} else if (searchBar.android) {
searchBar.android.clearFocus();
}当字符发生变化时搜索数据-在expors.loaded()中
我正在调用过滤器功能。Lodash _.debounce函数用于延迟resultList阵列的循环。没有它,每次输入字母时,应用程序都会循环运行。现在,我们正在等待用户停止键入以开始循环。
searchBar.on('propertyChange', _.debounce(searchList, 500));searchList函数
这是实际的循环。您可以根据需要更改element.name。
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()中
最后,如果用户清除搜索栏,我们希望隐藏键盘。
searchBar.on(searchBarModule.SearchBar.clearEvent, function (args) {
setTimeout(function() {
searchBar.dismissSoftInput();
}, 10);
});PS
你可能解决了你的问题,但这可能会对未来的其他人有所帮助。
发布于 2016-03-15 14:53:55
好的,你的问题是Javascript问题,而不是NativeScript问题。为了解决这个问题,可以观察到的数组仅仅是普通的数组。
在JS中,您正在创建一个新的PeopleListViewModel,然后通过pageData对象附加到bindingContext。到目前一切尚好。然后调用PeopleListViewModel上的PeopleListViewModel方法(它返回一个承诺,除了这个特定的问题之外,您并没有真正做任何事情)。
然而,当输入文本时,您并没有真正做任何事情。这是你的代码:
peopleList.filter(function (element, index, array) {
// DOESN"T WORK PROPERLY
console.log("element: ", JSON.stringify(element));
return element.fullName == searchText;
});peopleList是PeopleListViewModel的一个实例,它返回一个ObservableArray。ObservableArray确实有一个名为filter的方法(它的工作原理与常规数组的筛选器一样)。查看NativeScript文档和Javascript文档 of filter)。
这里您需要理解的是,filter 返回一个新的数组,其中包含过滤的结果。执行peopleList.filter()将将新数组发送到空空间。你想要var yourNewFilteredArray = peopleList.filter()。但是,您并不真的想重新定义绑定到绑定上下文的数组,而是要修改它的内容。
下面是一个如何做到这一点的例子:
/*
* 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);
}
});
});https://stackoverflow.com/questions/36005172
复制相似问题