2017-01-19 3 views
1

У меня есть следующий денормализованным Firebase структуру:вложенности Наблюдаемые с Angularfire2 (машинопись)

members 
    -memberid1 
    -threads 
     -threadid1: true, 
     -threadid3: true 
    -username: "Adam" 
    ... 

threads 
    -threadid1 
     -author: memberid3 
     -quality: 67 
     -participants 
     -memberid2: true, 
     -memberid3: true 
     ... 

И я перечисляю threads заказанный quality в моем компоненте:

признакам-threads.component.ts

constructor(af: AngularFire) { 
    this.threads = af.database.list('/threads', { 
     query: { 
      orderByChild: 'quality', 
      endAt: 10 
    } 
}); 

Вот отрывок из моего зрения:

признакам-threads.component.html

<div *ngFor="let thread of threads | async" class="thread-tile"> 
... 
    {{thread.author}} //Renders memberid3 
... 
</div> 

Вместо оказания memberid3 здесь, я хотел бы получить значение свойства имени пользователя для соответствующего члена.

Решения here и here и получают их наблюдаемые за пределами конструктора, а не внутри, как показано в Angularfire2 docs. Они используют this.af.database. Когда я использую ключевое слово внутри конструктора, TypeScript предупреждает, что он не распознает af как свойство компонента (потому что это явно не так). Я могу использовать за пределами конструктора, объявив свойство af: Angularfire;, но затем я получаю консольную ошибку TypeError: Cannot read property 'database' of undefined, которая, как я полагаю, связана с тем, что объявление свойства не совпадает с введением услуги AngularFire. Я пробовал некоторые другие вещи, которые, вероятно, слишком комичны, чтобы иметь отношение к этому вопросу.

Я не совсем уверен, что здесь происходит. Эта проблема мешает мне создать метод, к которому я мог бы просто передать значение author от threads в качестве параметра. Это связано с тем, что методы не могут быть определены внутри конструктора, а вне конструктора af имеет значение null.

Я даже не уверен, что это касается основного вопроса. Я хочу иметь возможность присоединяться/вставлять эти наблюдаемые в любое время, а не только в этом более простом случае, когда у меня есть преимущество прямого пути к memberid. Существует ряд вопросов, касающихся гнездования наблюдаемых, решения которых не используют Angularfire 2. К сожалению, я не смог перевести их в решение Angularfire 2.

Update

Я переехал всю логику я имел в компоненте к службе и теперь вводит метод сервиса getFeaturedThreads() в компонент со следующим:

ngOnInit() { 
    this.threads = this.featuredThreadsService.getFeaturedThreads() 
    this.threads.subscribe( 
     allThreads => 
      allThreads.forEach(thisThread => { 
       this.featuredThreadsService.getUsername(thisThread.author) 
        .subscribe( 
         username => console.log(username)) 
      }) 
    ) 
} 

getUserName() выглядит следующим образом:

getUsername(memberKey: string) { 
    return this.af.database.object('/members/' + memberKey + '/username') 
} 

на данный момент, это регистрирует username свойство для каждого member к й e console. К сожалению, я получил ключ. Значения являются пустыми:

enter image description here

...что странно для меня, учитывая тот факт, что getUsername() успешно передает идентификатор элемента в путь запроса.

enter image description here

Это захват с моей точки зрения Firebase консоли, который показывает правильный путь.

enter image description here

Я признаю тот факт, что это вопрос об использовании и не проблема с теч.

+1

Если вы хотите получить доступ к аф поле вне конструктора, добавить частное перед ним. 'private af: AngularFire'. Теперь вы можете сделать this.af.someMethod – Steveadoo

ответ

1

Я бы выполнил его так, я переместил его в ngOnInit, потому что вы действительно не должны делать это в конструкторе. Просто добавьте private перед объявлением af в своем конструкторе.

public ngOnInit() { 
    this.threads = this.af.database.list('/threads', { 
     query: { 
      orderByChild: 'quality', 
      endAt: 10 
     } 
    }).do(threads => { 
     threads.forEach(thread => { 
      thread.author = this.af.database.getName(thread.author); //actual method to get the username 
     }); 
    }); 
} 

И ваш компонент HTML

<div *ngFor="let thread of threads | async" class="thread-tile"> 
... 
    {{thread.author | async}} 
... 
</div> 
+0

Я получаю предупреждение машинописного текста, что свойство 'do' не выходит из типа' FirebaseListObservable '. –

+1

вам необходимо импортировать этого оператора. 'rxjs/add/operator/do' Я думаю. – Steveadoo

+0

Мне было бы интересно узнать, как вы определяете этот метод. Чтобы прикрепить 'do' к' this.threads', мне пришлось изменить тип с FirebaseListObservable на Observable. Поскольку метод не является методом «базы данных», я не вижу, как он привязан к нему. Я реализовал 'this.getUsername (thread.author);' После этих настроек мой метод возвращает объект, который отображается как '[object Object]'. –