Работа с Observables является асинхронной, поэтому в вашем примере это «возврат данных»; строка будет выполнена задолго до того, как «data = doc.payload.doc.get (« привилегии »);» выполняется.
Если метод getUserPrivilegeByUserId () находится в компоненте , подход к решению этой проблемы будет заключаться в том, чтобы установить данные как свойство компонента, а затем обновить их в подписке, например: ]
data: string;
...
getUserPrivilegeByUserId(uid:string){
this.db.collection('users', ref => { return ref.where('uid','==',uid)}).snapshotChanges().subscribe(result => {
result.forEach(doc =>{
this.data = doc.payload.doc.get("privileges");
})
}
);
}
Если, с другой стороны, метод getUserPrivilegeByUserId () живет в службе , вы можете вернуть Observable из службы следующим образом:
import { map } from 'rxjs/operators';
...
getUserPrivilegeByUserId(uid:string): Observable<string>{
return this.db.collection('users', ref => { return ref.where('uid','==',uid)}).snapshotChanges()
.pipe(
map(result => {
var data;
result.forEach(doc =>{
data = doc.payload.doc.get("privileges");
});
return data;
})
);
в вашем компоненте вы будете делать что-то вроде:
data: string;
...
this.userService.getUserPrivilegeByUserId(uid).subscribe(data => this.data = data);
a => a.Length
Я понимаю, что синтаксис, но как это связано с тем, что просит intellisense?
Этот блок кода является лямбда-выражением. Лямбда-выражение является удобным способом генерировать Анонимный метод (в этом случае) или Систему. Linq. Выражения. Выражение. Давайте сломаем его частями.
Func<string, object>
. Параметр для такой функции является строкой, таким образом, компилятор решает, что необходимость - строка. Единственной вещью, которую должен был обеспечить программист, является имя.Теперь, рассмотрите этот C# 2.0...
IEnumerable<string> sortedWords =
Enumerable.OrderBy(words, delegate(string a) {return a.Length;});
С C# 3.0
IEnumerable<string> sortedWords = words
.OrderBy(a => a.Length);
Я думаю, что IntelliSense на самом деле довольно полезен, специально для общих методов, которые берут Func<..>
введите как аргумент, потому что Вы видите, что типы и типы ведут Вас для понимания то, что мог бы сделать метод.
Например, аргументы в пользу OrderBy
IEnumerable<string>
как 'этот' аргумент, что означает, что у нас есть некоторый вход, содержащий набор строк. Первый аргумент keySelector
имеет тип Func<string, TKey>
, что означает, что это - некоторое лямбда-выражение, Вы обеспечиваете, что указывает, как добраться TKey
от string
.
Это уже предполагает, что метод, вероятно, перечислит по всем объектам (строки) в наборе, и он может использовать keySelector
получить значение типа TKey
от каждого элемента в наборе. Имя TKey
уже предполагает, что это будет использовать это значение для сравнения элементов (строки) с помощью этого расчетного ключа. Однако, если Вы смотрите на другую перегрузку, которая берет IComparer<TKey>
затем можно ли быть уверены в этом - этот аргумент указывает больше деталей о том, как Вы хотите сравнить два значения типа TKey
, таким образом, функция должна сравнить элементы с помощью этого ключа.
... этот вид размышления о типах занимает время для привыкания к, но после того как Вы изучите это, это может быть чрезвычайно полезно. Это более полезно в "функциональном" стиле кода, который часто использует много дженериков и lamdba выражений в C# 3.0 (и подобные вещи на функциональных языках как F# или другие)
Тип (как отображено Intellisense) имеет смысл, если Вы понимаете природу лямбда-выражений в.NET/C#. Иначе это может действительно казаться немного странным для вновь прибывшего. Начните путем полагания, что тип keySelector, Func <TSource, TKey> является просто делегатом. Перед C# 3.0 Вы назвали бы такой метод путем передачи делегата в качестве параметра, например:
IEnumerable<string> sortedWords = words.OrderBy(new Func<string, int>(mySelectorMethod));
где mySelectorMethod является названием обычного метода, который берет строку в качестве параметра и возвращает интервал (Как точка стороны, я предполагаю, что Вы могли использовать анонимных делегатов, но давайте не идти туда на данный момент.) Кроме того, обратите внимание, что этот пример чисто иллюстративен, поскольку LINQ почти всегда используется с.NET 3.5/C# 3.0 (хотя я полагаю, что это может использоваться с любой/и.NET 2.0/C# 2.0 - кто-то исправляет меня, если я неправ). Начиная с C# 3.0 методы могут быть определены встроенные как лямбда-выражения, которые предназначаются, чтобы использоваться при точно таких обстоятельствах как они. Перечитанный по статье MSDN о лямбда-выражениях (связанный выше), если Вы хотите получить надлежащее введение, но здесь я просто опишу использование в этом определенном контексте. Как Вы заявляете, Ваш код (в C# 3.0) является чем-то как следующее:
var sortedWords = words.OrderBy(a => a.Length);
Часть выражения, которое является a => a.Length
лямбда-выражение, которое является действительно просто сокращением от объявления встроенной функции. Синтаксис лямбда-выражений довольно прост по большей части; слева от => аргументы указаны, обычно в форме (arg1, arg2, arg3), но так как существует только один в этом случае, можно опустить скобки. Направо от => выражение, которое является возвращаемым значением функции (лямбда-выражение более точно). Кроме того, можно включить фактический код с оператором возврата в {и} хотя это является обычно ненужным. То, что я полагаю, что компилятор C# делает, распознает, что параметр передал OrderBy как лямбда-выражение и затем компилирует его в функцию и создает и передает делегата к Вам. Обратите внимание, что лямбда-выражения могут также быть преобразованы в Систему. Linq. Выражения. Объекты выражения (доступные деревья выражений) вместо делегатов, но это - намного менее общее использование. Так или иначе существует большое продолжение негласно здесь, но надо надеяться это должно, по крайней мере, разъяснить, почему типом является Func <TSource, TKey> и как это касается лямбда-выражения. Как я сказал, читайте на MSDN, если Вы хотите более глубокое понимание LINQ/lambdas/delegates...
Я никогда действительно волнуюсь о Intellisense, чтобы быть честным. Это портило меня рано в моем Linqage. Когда я провел больше времени с дженериками и выражениями, оно начало иметь смысл, но до тех пор я просто накачал в синтаксисе.
То, что это хочет, является лямбда-выражением, которое говорит Linq, что искать для сортировки набора.
Я чувствую Вас, моего брата, зависаю там, и это будет иметь смысл очень скоро.
OrderBy()
берет делегата к функции, которая принимает единственный параметр (в Вашем случае, a string
) и возвращает значение типа, который заменяют TKey
. Может случиться так, что тип параметра (строка) был уже определен, так как Вы обратились к методу IEnumerable<string>
но тип делегата будет только разрешен как Func<string,
int
>
после того, как это выведет его из лямбда-выражения, когда это полностью указано (т.е. a => a.Length
). Если Вы не дали синтаксическому анализатору ключа к разгадке относительно того, что Вы хотите как ключ сортировки, он просто покажет TKey в IntelliSense, пока он не сможет определить намеченный тип.