Soru angular2 async borusu, nesne verilerini şablona sığmaz


Şablonumda bir sözdizimi hatası olup olmadığını görmek için herkes yardımcı olabilir mi? Hata vermez, ancak verileri şablona da sığmaz.

<div *ngIf="(hero | async)">
  <h2>{{hero}}</h2>
  <h2>{{hero.name}} details!</h2>
  <div>
    <label>_id: </label>{{hero._id}}</div>
  <div>
    <label>name: </label>
    <input [(ngModel)]="hero.name" placeholder="name" />
  </div>
  <button (click)="goBack()">Back</button>
</div>

Bileşen kodu

export class HeroDetailComponent implements OnInit {
    errorMessage: string;

    //@Input() 
    hero: Observable<Hero>;

    constructor(
        private _heroService: HeroService,
        private _routeParams: RouteParams) {
    }

    ngOnInit() {
        let _id = +this._routeParams.get('_id');
        this._heroService.loadHero(_id);
        this.hero = this._heroService.hero$;
        this.hero.subscribe(data => 
           console.log(data)
        )
    }

Console.log (veri) yazdırır Nesne {_id: 11, ad: "Bay Nice"} Verilerin doğru şekilde alındığını.

<div> bloğu da gösterir, yani * boşluğu nesnenin boş olmadığını görür.

<h2>{{hero}}</h2> nesne nesnesini gösterir.

Fakat neden {{hero.name}} gösterilmiyor?


19
2018-04-22 21:12


Menşei


Bir kaç şey karışık. hero bir giriş özelliği, ancak sonra ngOnInit () de bir değer atarsınız. Atanan değer bir Gözlemlenmez. name Nedenini açıklayan özellik {{hero.name}}işe yaramayacak. Bu cevap size yardımcı olmalı: stackoverflow.com/a/34561532/215945 - Mark Rajcok
Yayını güncelledim ve @ girişini kaldırdım. Ama yine de aynı. Async borusunun gözlemlenebilir olanı kahraman nesnesine mi çevirmesi gerekiyor? - Shawn


Cevaplar:


Nesneler async borusu ile biraz zor. Bir dizi içeren Gözlemlenebilir ile, NgFor kullanabilir ve bir yerel şablon değişkeni oluşturabiliriz (hero async borusundan sonra dizinin her bir maddesine atanan diziler Gözlenebilir. Bu değişkeni şablonun başka bir yerinde kullanabiliriz:

<div *ngFor="let hero of heroes | async">
  {{hero.name}}
</div>
<!-- we can't use hero here, outside the NgFor div -->

Ama tek bir nesne içeren Gözlemlenebilir ile, o nesneyi referans verecek bir yerel şablon değişkeni oluşturmanın herhangi bir yolunun farkında değilim. Bunun yerine, daha karmaşık bir şey yapmamız gerekiyor:

<div>{{(hero | async)?.name}}</div>

Göstermek istediğimiz nesnenin her özelliği için bunu tekrarlamamız gerekecek. (Yukarıdaki satır, bileşen özelliğini varsayar. hero Gözlemlenebilir.)

Nesneyi atamak muhtemelen daha kolaydır (Gözlemlenebilir'in içinde, hero$ bileşen mantığını kullanarak, bileşenin bir özelliğine:

this._heroService.hero$.subscribe(data => this.hero = data.json());

ve sonra NgIf veya Elvis / güvenli navigasyon operatörü verileri görünümde görüntülemek için:

<div *ngIf="hero">{{hero.name}}</div>
<!-- or -->
<div>{{hero?.name}}</div>

51
2018-04-23 02:41



{{(kahraman | async) ?. name}} çalışmaz. İkinci yolu yaptım: Bileşen özelliğine veri almak ve şablona başvurmak için abone olun. Zaman ayırdığınız için teşekkürler. Bunu takdir ediyorum. - Shawn
<div> {{(kahraman | async) ?. name}} </ div> - bu sadece mükemmel. Beni çok zaman kurtardı ... - dot net learner
Başar, ikinci yol daha kolay ve düz ileri oldu :) - Al-Mothafar
Buraya geldim çünkü kodum şu anda önerdiğin 2. uygulamaya sahipti ve ben de Async boru. 2. uygulamayı tercih edenler için şunu unutmayın Async kodlamak zorunda kalmadan şifrelemeyi de içeren birçok faydası var - Luca


Başka bir seçenek @ Giriş ve akıllı / aptal bileşen yaklaşımını kullanmak olacaktır. Akıllı bileşeninizde async nesnesini aptal bileşenine iletebilir, sonra da dilsiz bileşende normal bir nesne gibi kullanabilirsiniz.

Fikir, akıllı bileşeninizin mantık ve veri ile uğraşması ve aptal bileşen tanıtımı ele almasıdır.

Akıllı bileşen:

<dumb-component [myHero]="hero$ | async"></dumb-component>

Aptal bileşen sınıfı:

@Input() myHero: Hero;

Aptal bileşen şablonu:

<div>{{ myHero.name }}</div>

21
2017-11-11 22:40



Bu benim görüşüme göre doğru bir yaklaşım - Amit
Bana çok zaman kazandı ve kabul edilen cevaptan çok daha iyi bir çözüm oldu imho. - mdziob
myHero bir dize doğru mu? '<Div> {{myHero.name}} </ div>' yerine <div> {{myHero}} </ div> 'olması gerekmiyor mu? - guilhebl
Güncelleme benim örneğim "myHero" bir cisim değil bir nesne olur. - chris cooley
Kabul edilen cevap. - Cody


Bu, şu anda v4.0.0'da bulunan 'as' sözdizimi kullanılarak mümkündür:

<span *ngIf="user$ | async as user; else loadingUserInfo">
 {{user.firstName}} {{user.lastName}}
</span>
<ng-template #loadingUserInfo>
  Loading user information...
</ng-template>

Daha fazla detay Github üzerinde RFC konu.


14
2018-03-28 20:19





Async borusunu ve bir parantez sözdizimini kullanmanız gerektiğinde akıllı / aptal bileşen yaklaşımının nasıl kullanılacağına dair sadece bir hassasiyet ekliyorum.

Bu bir hile birleştirin İşte.

< ui-gallery-image([image]="(imagesFB | async) ? (imagesFB | async)[0] : null") ></ui-gallery-image>

Bulmak için saatler harcıyorum. Umarım bu yardım. Bu konuda daha fazla bilgi Blog yazısı.


1
2018-01-05 13:54





Bir işlemek için en iyi yol Tek Gözlemlenebilir Nesne bir Angular 2.3.x veya Angular 4.x şablonunun içinde şablon değişkenli bir async borusu kullanmaktır.

İşte açısal geliştiriciler için ortak bir hedef. Redux'tan bir dizi eleman alın ve koleksiyondan tek bir eşleştirme elemanı koparın. Daha sonra bu tekil nesneyi bir şablonda oluşturun.

BİLEŞEN

@Component({
  selector: 'app-document-view',
  templateUrl: './document-view.component.html',
  styleUrls: ['./document-view.component.scss']
})
export class DocumentViewComponent implements OnInit {

  @select(['documents', 'items']) readonly documenList$: Observable<DocumentDTO[]>;
  public documentVO$: Observable<DocumentDTO>;

  constructor(private _state: NgRedux<IAppState>,
              private _route: ActivatedRoute,
              private _documentActions: DocumentActions) {

    _route.params.subscribe(params => {
      let modelId: number = parseInt(params['modelId']); //1          
      let documentId: number = parseInt(params['documentId']); //50
      this._documentActions.getDocument(modelId, documentId);
    });
  }

  ngOnInit() {

    //documenList holds all of the documents in our application state
    //but this view only wants a single element

    this.documentVO$ = this.documenList$.map(documents => documents.find(doc => doc.documentId === 50));
  }
}

GÖRÜNÜM

<div class="row" *ngIf="documentVO$ | async as dto">
    <div id="about" class="col-12">
        <div id="title" class="paper meta">
            <p>{{ dto.title }}</p>
        </div>
    </div>
</div>

1
2018-05-19 20:45