Если вы хотите получить все выбранные элементы, вы можете использовать свойство SelectedItems из ListBox. Вам не нужно добавлять свойство IsSelected к вашему объекту.
Проверьте пример.
Файл XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Button Content="Selected items" Click="Button_Click" />
<Button Content="Num of IsSelected" Click="Button_Click_1" />
</StackPanel>
<ListBox Name="lbData" SelectionMode="Extended" Grid.Row="1">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Grid>
Файл с кодом:
using System.Collections.Generic;
using System.Windows;
using System.Windows.Documents;
namespace ListBoxItems
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<MyBoundObject> _source = new List<MyBoundObject>();
for (int i = 0; i < 100000; i++)
{
_source.Add(new MyBoundObject { Label = "label " + i });
}
lbData.ItemsSource = _source;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(lbData.SelectedItems.Count.ToString());
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
int num = 0;
foreach (MyBoundObject item in lbData.Items)
{
if (item.IsSelected) num++;
}
MessageBox.Show(num.ToString());
}
}
public class MyBoundObject
{
public string Label { get; set; }
public bool IsSelected { get; set; }
}
}
Причина:
Причина, по которой это undefined
, заключается в том, что вы выполняете асинхронную операцию. Это означает, что потребуется некоторое время, чтобы закончить метод getEventList
(в зависимости от скорости вашей сети).
Итак, посмотрим на http-вызов.
this.es.getEventList()
После вас на самом деле сделать («пожар») ваш запрос http с subscribe
, вы будете ждать ответа. Во время ожидания javascript выполнит строки под этим кодом, и если он встретит синхронные назначения / операции, он немедленно их выполнит.
Итак, после подписки на getEventList()
и ожидания ответа,
console.log(this.myEvents);
строка будет выполнена немедленно. И значение этого параметра - undefined
до того, как ответ поступит с сервера (или во все, что вы его инициализировали в первую очередь).
Это похоже на выполнение:
ngOnInit(){
setTimeout(()=>{
this.myEvents = response;
}, 5000);
console.log(this.myEvents); //This prints undefined!
}
Решение:
Итак, как мы можем преодолеть эту проблему? Мы будем использовать функцию обратного вызова, которая является методом
blockquote>subscribe
. Потому что, когда данные поступают с сервера, они будут внутриsubscribe
с ответом.Поэтому изменение кода на:
this.es.getEventList() .subscribe((response)=>{ this.myEvents = response; console.log(this.myEvents); //<-- not undefined anymore });
будет печатать ответ .. через некоторое время. Что вы должны делать:
В вашем ответе может быть много чего другого, кроме как его регистрация; вы должны делать все эти операции внутри обратного вызова (внутри функции
subscribe
), когда данные поступают.Еще одна вещь, которая стоит упомянуть, состоит в том, что если вы исходите из фона
Promise
,then
обратный вызов соответствуетsubscribe
с наблюдаемыми. Что вам не следует делать:Не следует пытаться изменить операцию async на операцию синхронизации (но не на то, что вы можете). Одной из причин, по которым мы имеем асинхронные операции, является то, что пользователь не должен ждать завершения операции, пока они могут делать другие вещи за этот период времени. Предположим, что одна из ваших операций async длится 3 минуты, если у нас не было асинхронных операций, интерфейс застыл в течение 3 минут.
Рекомендуемое чтение:
Оригинальный кредит на этот ответ: Как вернуть ответ от асинхронного вызова?
Но с выпуском angular2 мы были введены для машинописных и наблюдаемых данных, поэтому этот ответ можно надеяться охватывает основы обработки асинхронного запроса с помощью наблюдаемых.
Вы можете просто попробовать этот метод -
let headers = new Headers({'Accept': 'application/json'});
let options = new RequestOptions({headers: headers});
return this.http
.get(this.yourSearchUrlHere, options) // the URL which you have defined
.map((res) => {
res.json(); // using return res.json() will throw error
}
.catch(err) => {
console.error('error');
}
Вы можете использовать asyncPype , если вы используете myEvents только в шаблоне.
Здесь пример с asyncPype и Angular4 HttpClient https://stackblitz.com/edit/angular -rhioqt? файл = приложение% 2Fevent.service.ts
также убедитесь, что вы сопоставляете свой ответ с выходом json. В противном случае он вернет обычный текст. Вы делаете это следующим образом:
getEventList(): Observable<any>{
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.get("http://localhost:9999/events/get", options)
.map((res)=>{ return res.json();}) <!-- add call to json here
.catch((err)=>{return err;})
}
Создание http-вызова в угловом / javascript - это асинхронная операция. Поэтому, когда вы делаете http-вызов, он назначит новый поток для завершения этого вызова и начнет выполнение следующей строки с помощью другого потока. Вот почему вы получаете неопределенное значение. поэтому сделайте ниже изменение, чтобы разрешить это
this.es.getEventList()
.subscribe((response)=>{
this.myEvents = response;
console.log(this.myEvents); //<-this become synchronous now
});