في الوقت الحالي ، من الممكن تمرير ملاحظة يمكن ملاحظتها وهي طريقة رائعة لتوسيع المكتبة. ومع ذلك ، فهو محدود بعض الشيء نظرًا لأن الاستخدامات لا يمكنها الوصول إلى الصورة بطريقة بسيطة.
تتمثل إحدى المشكلات الأكثر شيوعًا في عدم استخدام المستخدم للنافذة للتمرير أو استخدام مكتبة مكونة من 3 أجزاء تضيف طبقات تمرير إضافية (على سبيل المثال ، تصميم المواد الأيونية ، وغير ذلك) ، وقد يكون من الصعب أحيانًا العثور عليها إلى أي عنصر يتم تمريره بالفعل. قد تكون إحدى طرق حل هذه المشكلة هي استخدام Intersection Observer
(والذي يمكن أن يعطي أيضًا دفعة للأداء). على سبيل المثال.
@Component({
selector: 'intersection-observer',
template: `<img #img [defaultImage]="defaultImage" [lazyLoad]="image" [scrollObservable]="subject">`,
})
export class IntersectionObserverComponent {
@ViewChild('img') img;
subject = new Subject();
defaultImage = 'https://www.placecage.com/1000/1000';
image = 'https://images.unsplash.com/photo-1467932760935-519284fc87fa?dpr=2&auto=compress,format&fit=crop&w=1199&h=800&q=80';
ngAfterViewInit() {
const config = {
rootMargin: '50px 50px',
threshold: 0.01
};
function onIntersection(entries) {
entries.forEach(entry => {
if (entry.intersectionRatio > 0) {
observer.unobserve(entry.target);
this.subject.next();
}
});
}
const observer = new IntersectionObserver(onIntersection, config);
observer.observe(this.img.nativeElement);
}
}
لكن هذا مرهق للغاية.
ما يمكننا فعله هو قبول دالة كـ scrollObservable
، شيء مثل:
if (!this.scrollObservable) {
const windowTarget = isWindowDefined() ? window : undefined;
scrollObservable = getScrollListener(this.scrollTarget || windowTarget);
} else if (typeof this.scrollObservable === 'function') {
scrollObservable = this.scrollObservable(image, offset) // and maybe more
} else {
scrollObservable = this.scrollObservable.startWith('');
}
لا يمكننا إعادة كتابة المكون أعلاه إلى:
@Component({
selector: 'intersection-observer',
template: `<img [defaultImage]="defaultImage" [lazyLoad]="image"
[scrollObservable]="startLazyload" offest="50">`,
})
export class IntersectionObserverComponent {
defaultImage = 'https://www.placecage.com/1000/1000';
image = 'https://images.unsplash.com/photo-1467932760935-519284fc87fa?dpr=2&auto=compress,format&fit=crop&w=1199&h=800&q=80';
startLazyload(image, offset) {
Observable.create(observer => {
const intersectionObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.intersectionRatio > 0) {
observer.next();
}
});
}, {
rootMargin: offset ? `${offset}px` : undefined,
threshold: 0.01
});
intersectionObserver.observe(image);
return () => observer.unobserve(image);
});
}
}
أفضل ولكن لا يزال صاخبًا بعض الشيء ، خاصةً عندما يريد المستخدم استخدام IntersectionObserver
على جميع الصور.
قد تكون إحدى طرق حل هذه المشكلة هي تمرير القيمة الافتراضية القابلة للملاحظة في NgModule
:
import { intersectionObserverLazyLoad } from 'some-place';
@NgModule({
declarations: [ AppComponent ],
imports: [ BrowserModule, lazyLoadImage({
observable: intersectionObserverLazyLoad
})],
bootstrap: [ AppComponent ]
})
export class MyAppModule {}
لا يمكننا إعادة كتابة المكون أعلاه إلى:
@Component({
selector: 'intersection-observer',
template: `<img [defaultImage]="defaultImage" [lazyLoad]="image" offest="50">`,
})
export class IntersectionObserverComponent {
defaultImage = 'https://www.placecage.com/1000/1000';
image = 'https://images.unsplash.com/photo-1467932760935-519284fc87fa?dpr=2&auto=compress,format&fit=crop&w=1199&h=800&q=80';
}
يمكن أن تفتح القدرة على تمرير الوظائف الافتراضية في NgModule أيضًا أبوابًا لإنشاء وظائف مخصصة مقابل isVisible
و loadImage
لكن هذه قصة لاحقة.
سيحل: # 287 ، # 195 ، # 286 ، # 285 ، # 275 ، # 259 وأكثر. يتم حل معظم المشكلات بطرق أخرى ولكن سيكون من الجيد أن نمنح المستخدم مزيدًا من المرونة عند إنشاء ملف يمكن ملاحظته.
ما رأيك sapierens ،rimlin؟
tjoskar كما أفهم أنك تريد تحسين scrollObservable
خلال توفير وظيفة كخيار لـ scrollObservable
، والذي سيعيد Observable ، وهو المسؤول عن إصدار حدث تحميل الصورة؟ إذا كان الأمر كذلك ، أعتقد أنها فكرة رائعة حقًا!
لكني أعتقد أنه من الأفضل استخدام الكائن بدلاً من تعداد الحجج:
...
} else if (typeof this.scrollObservable === 'function') {
scrollObservable = this.scrollObservable({
image,
offset
});
} else {
...
توفير وظيفة كخيار لـ scrollObservable ، والذي سيعيد Observable ، وهو المسؤول عن إرسال حدث تحميل الصورة
هذا صحيح ، قد أرغب أيضًا في إعادة تسمية scrollObservable
لكن هذا سيكون تغييرًا مفاجئًا.
أعتقد أنه من الأفضل استخدام الكائن بدلاً من تعداد الحجج
يوافق!
أعتقد أن هذه فكرة جيدة ، لا سيما تمرير مراقب افتراضي.
أعتقد أنه من الأفضل استخدام الكائن بدلاً من تعداد الحجج
أوافق أيضا على هذا.
ثابت في # 365 وفي الإصدار 2.1.0
التعليق الأكثر فائدة
tjoskar كما أفهم أنك تريد تحسين
scrollObservable
خلال توفير وظيفة كخيار لـscrollObservable
، والذي سيعيد Observable ، وهو المسؤول عن إصدار حدث تحميل الصورة؟ إذا كان الأمر كذلك ، أعتقد أنها فكرة رائعة حقًا!لكني أعتقد أنه من الأفضل استخدام الكائن بدلاً من تعداد الحجج: