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...
- İlgili nesnenin bir sınıfa sahip olduğundan emin olun (bu durumda Car sınıfı)
- Sınıfa,
return { self: this };döndüren birget observe()getter ekleyin - Sınıftaki her özelliği ile @computedFrom(... ekleyin.
- HTML'inizde, bu bağlamayı istediğiniz yere
car.observe.selfile 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.
