2016-12-06 1 views
0

У меня есть случай, когда я отображать некоторую информацию пользователя с помощью трубы:Информация о пользователе не отображается

{{ author.id | user: 'name' }}

я получаю id от автора, а затем, я использую user трубу, чтобы получить его информация хранится в /users/$uid. Вот моя труба:

export class UserPipe implements PipeTransform { 
    constructor(private af: AngularFire) {} 

    transform(uid: string, field: any): any { 
    let data = {}; 

    let fb = this.af.database.object(`/users/${uid}`); 
    fb.subscribe(res => { 
     data = res; 
     console.log(data[field]); 
    }); 

    return data[field]; 
    } 
} 

Это прекрасно работает, если автор является текущим вошедшим в систему пользователем. Однако это имя не отображается для других.

Это имя обычно печатается на консоли, однако оно все еще не отображается в HTML. Я также дважды проверил правила безопасности Firebase, и все в порядке. Я не получаю никаких ошибок в консоли.

+0

Выполняется асинхронный запрос, что означает, что вы возвращаете данные [поле] ', прежде чем данные будут назначены в вызове. – silentsod

+1

Вы можете подумать о том, чтобы сделать эту трубку «трубой async», вернуть 'this.af.database.object ('/users/$ {uid} ')' из 'Pipe' и на просмотр, а затем использовать {{(author.id | user | async)? .name}} –

+0

Как я могу следить за изменениями в трубе? Вы знаете, почему этого не происходит, когда автор вошел в систему? – brians69

ответ

2

Ваша функция transform() использовала наблюдаемый. Самый простой подход - обернуть ваш результат AsyncPipe, если вы хотите консолидировать логику отображения в трубе.

@Pipe({ 
    name: 'user', 
    pure: false 
}) 
export class UserPipe implements PipeTransform { 
    private asyncPipe: AsyncPipe; 

    constructor(ref: ChangeDetectorRef, private af: AngularFire) { 
    this.asyncPipe = new AsyncPipe(ref); 
    } 

    transform(uid: string, field: any): any { 
    let fb = this.af.database.object(`/users/${uid}`).map(res => res[field]); 
    return this.asyncPipe.tranform(fb); 
    } 
} 

Или, если вы хотели бы реализовать эту функцию в компоненте, хотя и не рекомендуется, просто для удовольствия

@Component({ 
    selector: 'my-user', 
    template: '{{ result | async }}' 
}) 
export class UserComponent { 
    @Input() uid: string; 
    @Input() field: string; 
    result: Observable<any>; 

    constructor(private af: AngularFire) {} 

    ngOnChanges(changes: SimpleChanges) { 
    let field = changes.field.currentValue; 
    let uid = changes.uid.currentValue; 
    if (uid && field) { 
     this.result = this.af.database.object(`/users/${uid}`).map(res => res[field]); 
    } 
    else { 
     this.result = Observable.of(null); 
    } 
    } 
} 

Используйте с:

<my-user uid="12345" field="name"></my-user> 

или в качестве альтернативы, вы можете просто сделайте то, что предлагается в комментарии, только return this.af.database.object('/users/uid') и проведите трубку с помощью трубы async.