TypeScript - HTTP ואובייקטים מקוננים (Angular2 RC1 + TS)


אני נתקל בקשיים בהצגת הנתונים שלי בדפדפן. כדי להסביר את הבעיה שלי אני משתמש בקוד דמה. יש לי כמה אובייקטים מקוננים שגורמים לבעיה שלי. כאן אני אציג אובייקט מקונן אחד כדי להראות את הבעיה שלי.

ראשית כל, אני רק מבצע קריאות HTTP עבור אובייקט הרכב. אז saveCar מתפקד גם כמו עדכון של הרכב, בהתאם למה שהמשתמש עושה באפליקציה. כל השיטות בשירות פועלות כפי שהן אמורות.

אז השירות שלי נראה משהו כזה:

@Injectable()
export class Service {

    constructor(private http: Http) { }

    saveCar(car: Car) {
       return this.http.post ....      
    }

    getCars(){
        return this.http.get...       
    }

    getById(id: string) {
        return this.http.get...       
    }    
}

אז יש לי מחלקת Car, שבה האובייקט המקונן "Brand" נכנס לפעולה, ל-Brand יש אז מחלקה משל עצמה, אבל אני אשתאיר אותה החוצה.

export class Car {

    private brands: Array<Brand>;

    constructor(public id: string, public name: string) {
        this.brands = new Array<Brand>();
    }

    public getBrands(): Array<Brand> {
        return this.brands;
    }

    public addBrand(value: Brand): void {
        this.brands.push(value);
    }
    //some other methods.
}

אז יש לי מרכיב רשימה שמציג את כל המכוניות, זה עובד כפי שצריך!

@Component({
    selector: 'car-list',
    template: `
    <h1>Add Car</h1>
    <form (submit)="saveCar()">
        <input required [(ngModel)]="name" placeholder="Add car">
    </form>
    <br>
    <table>
        <tr *ngFor="let car of cars" >
        <td>{{car.name}}</td>
        <td><button (click)="goToDetail(car)">Detail</button></td>
        </tr>
    </table>
  `,
})


export class ListComponent implements OnActivate {
    id: string
    name: string;
    cars: Array<Car>

    constructor(public _service: Service, public _router: Router) {   }

    routerOnActivate(): void {
        this._service.getCars()
            .subscribe(cars => this.cars = cars);
    }

    saveCar() {
        let car = new Car(this.id, this.name)

        this._service.saveCar(Car)
            .subscribe(car => this.cars.push(car));

        this._service.getCars()//
            .subscribe(cars => this.cars = cars);
    }

    goToDetail(car:Car) {
        this._router.navigate(['/cardetail', car.id]);
    }

}

הבעיה שלי היא ברכיב הפרטים, שם המשתמש מנותב לאחר לחיצה על רכב מסוים. הניווט ושליפת הרכב מהבסיס נתונים פועלים כפי שצריך. אני יודע זאת, כי אם אני מסיר את כל התבנית חוץ מ-<h1>רכב: {{car?.name}}</h1> השם מודפס כראוי עם אופרטור אלביס.

אבל הרכיב-פרט שלי נראה משהו כזה:

@Component({
    selector: 'car-detail',
    template: `  
    <h1>Car: {{car?.name}}</h1>
    <hr>
    <button (click)="addBrand()">Add Brand</button>      
    <div *ngFor="let brand of car.getBrands(); let i=index">  
    <h2>Brand {{i+1}}</h2>
    </div>               
`,
})

export class DetailComponent implements OnActivate {

    @Input() car: Car;

    constructor(public _service: Service, public _router: Router) {    }

    routerOnActivate(curr: RouteSegment): void {
        let id = curr.getParam('id');
        this._service.getById(id)
            .subscribe(car => {
                this.car = car;
            });
    }

    addBrand() {
        this.car.getBrands().push(new Brand());
    }

    //some other methods
}

אז ברכיב הפרטים שלי אני קורא לכל המתודות כמו: car.someMethod() ובהמשך את אובייקט המותג המקונן כמו: brand.someMethod() בתבנית. אז השגיאה מגיעה בקריאה של השיטה, למשל בתבנית 'cannot get getBrands of undefined' ניסיתי לשים את האופרטור של Elvis כך: car?. getBrands() זה לא עובד. ניסיתי לעטוף את הכל ב-div, גם עם אופרטור אלביס וגם <div *ngIf="car"></div>, זה לא עובד. אפילו ניסיתי עם <template *ngIf="car"></template>, גם זה לא עובד....

עריכה: הטעות שלי, לעטוף כך למטה, זה "באופן מסוים" עובד, כלומר, זה נותן שגיאה חדשה....

תבנית :

@Component({
    selector: 'car-detail',
    template: `  
    <h1>Car: {{car?.name}}</h1>
    <hr>
    <button (click)="addBrand()">Add Brand</button>
    <div *ngIf="car">      
      <div *ngFor="let brand of car.getBrands(); let i=index">  
      <h2>Brand {{i+1}}</h2>
      </div>   
    </div>   

תשובה #1

אתה מזכיר <h1>Car: {{car?.name}}</h1> עם ? אבל הדוגמה המלאה של הקוד כוללת <td>{{car.name}}</td> בלי ? מה שיגרום לשגיאה.

<div *ngFor="let brand of car.getBrands(); let i=index">  

גם צריך ? כדי למנוע שגיאות כאשר Angular מנסה להציג את התצוגה ו-car עדיין לא מוגדר

<div *ngFor="let brand of car?.getBrands(); let i=index">