TypeScript - Özellikler değiştiğinde Aurelia bağlamasını güncelle


TypeScript ile Aurelia kullanıyorum. Bir nesneyi görünüme bağlamaya çalışıyorum ve nesnemin bir özelliğini değiştirdiğimde görünümün güncellenmesini istiyorum. Aurelia'nın yalnızca nesneyi ve bazı dizi manipülasyonlarını (push, splice vb.) izlediğini biliyorum. Ayrıca @computedFrom gibi bazı bağlama yardımcıları ve BindingEngine kullanımı olduğunu da biliyorum, ancak yine de değer dönüştürücüleri kullanırken en iyi yaklaşımı bulamıyorum.

Örneğimde TypeScript'te bir sınıfım var, örneğin "class Car". Daha sonra birden fazla araba nesnesini görünüme bağlıyorum, örneğin ${car1}, ${car2} vb. Arabayı sunmak için bir değer dönüştürücü ekliyorum, örneğin ${car1 | carPresenter}. Bu bilgiyi şu şekilde gösteriyor: "Tam depo ve üç yolcusuyla mavi bir araba". Bir araba özelliğini değiştirirsem, örneğin "car1.passengers++", o zaman ${car1 | carPresenter} güncellensin istiyorum.

Belki bir değer dönüştürücü yanlış bir yaklaşım olabilir? Eğer durum buysa, daha iyi yöntemler hakkında lütfen tavsiye verin. Karmaşık nesneleri, bazı özelliklerini göstererek sunmak istiyorum ama mutlaka hepsini değil. Ve bu sunumlar, temel özellikler değiştiğinde güncellenmelidir.

Sorunu gösteren basitleştirilmiş bir örnekle bir gist oluşturdum: https://gist.run/?id=06287de5eb179b32fa0b134eb59ebc68

Cevap #1

Kullanabileceğiniz ek bir bağlama dekoratörü vardır: @observable [ilgili belgeler].

Daha fazla bilgi: Aurelia ile Çalışmak @observable (Dwayne'in blogu, Aurelia öğrenmek için son derece yararlı bir kaynaktır).

Gist demosu: https://gist.run/?id=c359860951717457e630e3fde1a4d6aa

Bu demo'da, Car nesnesinin tüm gerekli özelliklerinin @observable dekoratörüyle tanımlandığı kendi sınıfı vardır. Değer dönüştürücü, description getter metodu ile değiştirilmiştir.

Araba sınıfı

import { observable } from 'aurelia-framework';

export class Car {
    @observable
    color;

    @observable
    gasLevel;

    @observable
    passengers;

    constructor(data) {
        // ...
    }

    get description() {
        return `A ${this.color} car with ${this.gasLevel} tank and ${this.passengers} passengers`;
    }
}

Cevap #2

Eğer iç değişikliklere bağlanmak ve tepki vermek istiyorsanız, işte benim küçük bir numaram...

  1. İlgili nesnenin bir sınıfa sahip olduğundan emin olun (bu durumda Car sınıfı)
  2. Sınıfa, return { self: this }; döndüren bir get observe() getter ekleyin
  3. Sınıftaki her özelliği ile @computedFrom(... ekleyin.
  4. HTML'inizde, bu bağlamayı istediğiniz yere car.observe.self ile bağlayın
  • Not: Sınıftaki her özelliğin varsayılan bir değeri veya bir dekoratörü olduğundan emin olun.
    Aksi takdirde computedFrom’ın 'tutunacak' bir yeri olmaz.
    Daha iyi bir açıklama için bu SO cevabına bakın: Aurelia'nın bir nesne ile kullandığı computedFrom

Yani sizin durumunuzda Car sınıfının şöyle görünen bir getter'a sahip olması gerekir:

@computedFrom('color', 'gasLevel', 'passengers')
get observe() {
  return { self: this };
}

Ve HTML bağlamanız şöyle görünecektir:

<strong>car: </strong>${car.observe.self | carPresenter}

Hızlı, basit, okunabilir ve işi hallediyor (ve iç gözlem yuvasını destekliyor).


Tam kod:

app.js

import { Car } from './car';

export class App {
  car = new Car({
    color: 'blue',
    gasLevel: 'full',
    passengers: 1
  });
  
  attached() {
    this.increasePassengers();
  }
  
  increasePassengers() {
    this.car.passengers++;
    setTimeout(() => { this.increasePassengers(); }, 1000);
  }
}

araba.js

import { computedFrom } from 'aurelia-framework';

export class Car {
  color = undefined;
  gasLevel = undefined;
  passengers = undefined;
  
  constructor(data) {
    const values = data || {};
    const fieldNames = Object.getOwnPropertyNames(values);
    for (let field of fieldNames) {
      if (field in this) {
        this[field] = values[field];
      }
    }
  }
  
  @computedFrom('color', 'gasLevel', 'passengers')
  get observe() {
    return { self: this };
  }
}

S: Neden basitçe get self(): { return this; } kullanmıyoruz?
C: Aurelia bunun için çok zekidir; aynı referansın döndürüldüğünü görür ve onu görmezden gelir.

İlgili makaleler