Angular: الاقتراح: الإدخال كما يمكن ملاحظته

تم إنشاؤها على ٨ ديسمبر ٢٠١٥  ·  183تعليقات  ·  مصدر: angular/angular

آسف أنا لست جيدة في اللغة الإنجليزية.

يتم توفير قيم خاصية @Input بواسطة المكون الرئيسي. التغييرات تأتي بشكل غير متزامن.
وإذا تم تغيير خاصية الإدخال في المكون الفرعي (لها الخاصية كخاصية خاصة) ، فلن يلاحظها كاشف التغيير أبدًا.

المرمى

  • يجب مزامنة بيانات الإدخال الخاصة بالوالد وخاصية الإدخال الخاصة بالطفل.
  • يجب أن يفهم المطورون أن خصائص الإدخال تتغير بشكل غير متزامن.

    عرض

@Component({ selector: "child" })
class Child {
  @Input("input") inputValue: Observable<T>;

  ngOnInit() {
    this.inputValue.map((value)=>...);
  }
}

@Component({
  template: `
  <child [input]="valueToChild"></child>
  `
})
class Parent {
  valueToChild: T;
}

رمز أعلاه لا يعمل. حاليًا ، لتلقي الإدخال كـ Observable<T> ، يجب أن أكتبه على النحو التالي.

@Component({ selector: "child" })
class Child {
  @Input("input") inputValue: Observable<T>
}

@Component({
  template: `
  <child [input]="valueToChild"></child>
  `
})
class Parent {
  valueToChild: Observable<T> = new Observable<T>((observer)=>{
    ...
    observer.next(val);
  });
}

مثال: http://plnkr.co/edit/BWziQygApOezTENdTVp1؟p=preview

هذا يعمل بشكل جيد ، لكنه ليس ضروريًا. بيانات الإدخال للوالدين هي بيانات بسيطة في الأصل.

أعتقد أن هذا الاقتراح يجعلنا سعداء.

شكرا.

core inputs / outputs feature Needs Design

التعليق الأكثر فائدة

عزيزي فريق Angular. يرجى إعطائنا شيئًا نتطلع إليه في عام 2020 :-)

أيضًا حل jcomputer هو بالضبط ما @ViewChild { read } . على سبيل المثال:

@Input({ observable: true }) 
@Input({ asObservable: true }) 
@Input({ asSubject: true })

ال 183 كومينتر

مرحبًا @ laco0416 - لغتك الإنجليزية جيدة ، لا تقلق!

تعجبني هذه الفكرة كثيرًا ، وقد ناقشناها من قبل. كما أنه يتطابق بشكل جيد مع https://github.com/angular/angular/issues/4062 (مشاهدة أحداث العرض) و https://github.com/angular/angular/issues/5467 (أحداث أطفال ملحوظة من الوالدين)

من المهم أن تتذكر أنه لن يرغب الجميع في استخدام Observables (هؤلاء الأشخاص يفقدون الفرصة!) ، لذلك يجب أن نقدم خيارات لكلتا حالتي الاستخدام ، وبالتالي فمن غير المحتمل أن نجعل @Input() مباشرة في Observable. أعتقد أن الحصول على شيء مثل @ObserveInput() قد ينجح ، وسنناقش _ بعد_ نشحن تجريبيًا حول بعض هذه الميزات الأكثر إثارة للاهتمام على ما أعتقد.

في هذه الأثناء ، إليك تطبيق أساسي (وتجريبي للغاية !!! لا تفعل هذا بشكل حقيقي) لهذه الفكرة. هل هذا من الناحية المفاهيمية ما كنت تفكر فيه؟ http://plnkr.co/edit/Nvyd9IPBZp9OE2widOcW؟p=preview

أعتقد أنها فكرة سيئة للغاية تغيير خصائص الإدخال في المكون الفرعي. يجب أن تكون خصائص الإدخال "للقراءة فقط". يجب أن تتدفق بياناتك دائمًا من الوالد إلى الطفل (وليس في الاتجاه العكسي أبدًا).

alexpods أعتقد أن الفكرة هنا هي بالضبط - _ الاستماع_ إلى التغيير في خصائص الإدخال _ كما_ يمكن ملاحظته ، وليس إصدار قيم في المنبع ، وهو أمر جيد تمامًا بقدر ما أشعر بالقلق.

تضمين التغريدة

لغتك الإنجليزية جيدة ، لا تقلق!

شكرا لك! أنا مرتاح جدا.

@ObserveInput هو ما أريده!
أيضًا ، @Input ليس به تغييرات فاصلة. أعتقد أنه حل جيد للغاية.

alexpods أنا أيضًا على الإطلاق.

إن الاستماع إلى التغيير في خصائص الإدخال يمكن ملاحظته ، وليس إصدار قيم في المنبع ، وهو أمر جيد تمامًا بقدر ما أشعر بالقلق.

أعتقد بنفس طريقة روب.

@ laco0416 أوه ، آسف لسوء الفهم. لقد أربكتني عبارة "إذا تم تغيير خاصية الإدخال في المكون الفرعي".

لا أعرف ما إذا كان عليّ التعليق هنا أم يجب فتح عدد جديد. يرجى إعلامي إذا كنت أقوم بإضافة طلب إلى المكان الخطأ.

لقد كنت أحاول (ولكن حتى الآن ، أفشل ) أن أكتب مثل هذا plunkrrobwormald ، الذي يعمل _ تقريبًا_ بشكل مثالي (ولكن ليس تمامًا).

ما جعلني متحمسًا لهذا النهج هو حقيقة أنه يستفيد من خطاف دورة الحياة ngOnChanges .
ما أود رؤيته هو طريقة ما لعرض خطافات دورة الحياة _all_ على أنها قابلة للملاحظة ، مثل onChanges$: Observable<{[key: string]: SimpleChange}> ، onInit$: Observable<{}> ، إلخ.

إن توفر كل خطافات دورة الحياة المتاحة مثل Observables سيساعدني في Rx لجميع الأشياء ؛-)

أي تحديثات على هذا؟

AFAIK ، لا.
robwormald هل لديك أي أخبار؟

أعلم أن هذا قديم ، لكن هذا سيكون رائعًا! robwormald أي كلمة في هذا؟

أرغب في تقديم قيم خاصية @Input المتغيرة باعتبارها قابلة للملاحظة ، تمامًا كما يفعل مصممrobwormald @ObserveInput . ليس من الممكن دائمًا أن تجتاز المكونات الرئيسية Observables ، خاصةً عندما تقوم بترحيل تطبيق (Angular 1) موجود. غير أن عدم القدرة على "احتواء" العناصر المرصودة داخل مكون واحد يجعل الاستفادة من قوة وأناقة RxJS أكثر صعوبة.

لسوء الحظ ، لم يكن روب يمزح عندما قال عدم استخدام هذا الإصدار من @ObserveInput . المشكلة التي أواجهها هي أن الملاحظات يتم إنشاؤها على "مستوى الفصل" (إذا كانت هذه المصطلحات منطقية) ومن ثم يتم مشاركتها عبر جميع مثيلات المكون. من الواضح أن هذا ليس جيدًا. لم ينجح إنشاء الملاحظات في وقت إنشاء مثيل بالنسبة لي أيضًا. يبدو أن Angular لا يعمل بشكل صحيح على اكتشاف التغيير في هذه الحالة.

هل تمكن أي شخص من تنفيذ تطبيق أفضل @ObserveInput أم أن هناك أي أخبار عن الدعم الرسمي؟

lephyrus في حين أن مصمم الديكور الرسمي @ObserveInput سيكون لطيفًا جدًا ، إلا أنه ليس ضروريًا تمامًا للحصول على ملاحظة لتغيير قيم ملكية @Input . سيكون المصمم ببساطة "سكر" أنيق للغاية.

يوجد بالفعل حدث دورة حياة ngOnChanges . داخل ngOnChanges يمكننا استخدام rxjs Subject ، لإنشاء تغييرات يمكن ملاحظتها ، على سبيل المثال:

<strong i="13">@Input</strong> inputString: string;
private Subject<string> inputString$ = new Subject<string>;

ngOnChanges(changes: { [key: string]: SimpleChange }) {
    if (changes.hasOwnProperty('inputString')) {
        this.inputString$.next(changes['inputString'].currentValue);
    }
}

constructor() {
    inputString$.subscribe(x => {
        console.log('inputString is now', x);
    });
}

أو ، إذا كنت تريد شيئًا أكثر قابلية لإعادة الاستخدام ، فيمكنك إنشاء فئة أساسية لمكونك extends :

import { SimpleChange } from '@angular/core';
import { Observable, ConnectableObservable, Observer } from 'rxjs';

export interface TypedSimpleChange<T> {
    previousValue: T;
    currentValue: T;
}

export class ReactiveComponent {
    private changesObserver: Observer<{ [key: string]: SimpleChange }>;
    private changes$: ConnectableObservable<{ [key: string]: SimpleChange }>;

    constructor() {
        this.changes$ = Observable.create((observer: Observer<{ [key: string]: SimpleChange }>) => this.changesObserver = observer).publishReplay(1);
        this.changes$.connect();
    }

    public observeProperty<T>(propertyName: string): Observable<TypedSimpleChange<T>> {
        return this.changes$
            .filter(changes => changes.hasOwnProperty(propertyName))
            .map(changes => changes[propertyName]);
    }

    public observePropertyCurrentValue<T>(propertyName: string): Observable<T> {
        return this.observeProperty<T>(propertyName)
            .map(change => change.currentValue);
    }

    ngOnChanges(changes: { [key: string]: SimpleChange }) {
        this.changesObserver.next(changes);
    }
}

... والتي يمكن استخدامها على النحو التالي:

@Component({
    ...
})
export class YourComponent extends ReactiveComponent {
    @Input() inputString: string;

    constructor() {
        super();
        this.observePropertyCurrentValue<string>('inputString')
            .subscribe(x => console.log('inputString is now', x));
    }
}

أنا أستخدم هذا الأسلوب حتى يتوفر مصمم رسمي @ObserveInput .

شكرا ياwmaurer. إن ReactiveComponent مرحب به للغاية ، واستخدام رمز لا تشوبه شائبة وكتابة آمنة للتمهيد - رائع حقًا! الأهم من ذلك ، أنه يتصرف أيضًا بشكل جيد تحت الاختبار ولا يزال يسمح باستخدام استراتيجية الكشف عن التغيير OnPush . أنا الآن سعيد بانتظار "السكر الرسمي". (أنا متأكد أيضًا من أنني سأتعلم شيئًا ما عندما أكتشف سبب وجوب استخدام المنطق Observable.create() - لم أجد وقتًا للنظر فيه بعد.) مرة أخرى: merci gäll! :غمزة:

lephyrus على الرحب والسعة ، gärn gescheh ؛-)

لقد استخدمت Observable.create() للحصول على Observer حتى أتمكن من القيام بـ next() . كان بإمكاني استخدام Subject وهو Observable و Observer ، لكنني أعتقد أنه من الممارسات السيئة عمومًا "كشف" Subject ( Observer ).

@ laco0416 أغلق لصالح https://github.com/angular/angular/issues/13248 ؟

DzmitryShylovich لا. الميزة المقترحة في هذه المشكلة للقراءة فقط وتمرير البيانات التي تعتمد على الأحداث.

@ObserveInput سيكون رائعًا جدًا! : +1:

شكرا لك wmaurer على مثال جيد. لدي سؤال واحد على الرغم من. أود أن أكون قادرًا على استخدام كائن بدلاً من سلسلة كسلسلة يمكن ملاحظتها.

على سبيل المثال

@Input() chartConfig: ChartConfig;

constructor(private _reportService: ReportService) {
        super();
             this.observePropertyCurrentValue<string>('chartConfig')
            .subscribe(changedConfig => this.updateChart(changedConfig));
 }

export class ChartConfig {
    public id: string;
    public type: any;
    public data: any;
    public labels: any;
}

ومع ذلك ، لم يتم استدعاء this.updateChart و ngOnChanges. كيف يمكنك توسيع عينتك من سلسلة بسيطة لرصد كائن بدلاً من ذلك؟

ChrisWorks يجب أن تعمل أيضًا مع الكائنات:

this.observePropertyCurrentValue<ChartConfig>('chartConfig')
            .subscribe(changedConfig => console.log(changedConfig));

أفعل هذا كثيرًا ، لذا إذا لم ينجح ذلك ، أعتقد أن هناك مشكلة في الإدخال إلى المكون الخاص بك في مكان ما.

مرحبًا wmaurer ، شكرًا على الرد. هل ستكون قادرًا على توسيع عينتك بإصدار عمل حيث تستخدم كائن "config"؟ أنا ببساطة لا أستطيع الحصول على العمل الخاص بي. نموذج Git repo؟ :)

ChrisWorks يجب أن تعمل بالطريقة التي هي عليها. لا يفرق observePropertyCurrentValue بين إدخال سلسلة وكائن.
هذا مشروع ng2 beta 0 قديم حقًا قمت بإنشائه حيث تكون المدخلات من جميع الأنواع المختلفة ، وليس مجرد سلاسل:
https://github.com/wmaurer/todomvc-ng2-reactive
على سبيل المثال https://github.com/wmaurer/todomvc-ng2-reactive/blob/master/src/app/todo-item/todo-item.component.ts

+1 حالة استخدام أساسية كهذه ، لا أصدق أنه لم يتم فرزها بعد!

لقد حصلت أخيرًا على أفضل حل وهو يعمل بدون تكرار ومع تجميع AOT :) السر هو الجمع بين @Input() مع مصمم ثانٍ.

المصمم:

import { ReplaySubject } from 'rxjs/ReplaySubject'                                                                                                 

const subjects = new WeakMap()                                                                                                                     

export function ObservableInput() {                                                                                                
  return (target, propertyKey) => {                                                                                                                
    delete target[propertyKey]                                                                                                                     

    Object.defineProperty(target, propertyKey, {                                                                                                   
      set(value) {                                                                                                                                 
        this[propertyKey].next(value)                                                                                                              
      },                                                                                                                                                                                                                            
      get() {                                                                                                                                      
        let subject = subjects.get(this)                                                                                                           
        if (! subject)  {                                                                                                                          
          subject = new ReplaySubject<any>(1)                                                                                                      
          subjects.set(this, subject)                                                                                                              
        }                                                                                                                                          
        return subject                                                                                                                             
      },                                                                                                                                           
    })                                                                                                                                             
  }                                                                                                                                                
}                                                                                                                                                  

استعمال:

class SomeComponent {
  @Input() @ObservableInput()                                                                                                                    
  public index: Observable<number>
}                                                                                                               

تحرير: لقد جعلت هذه مكتبة الآن. يسعدني تلقي الأفكار لتحسينه. إضافة طريقة جديدة تكمل @Input مع Observable التالي. راجع https://github.com/ohjames/observable-input

إذا اضطررت إلى القيام بشيء من هذا القبيل ، فإنني أفضل الانتقال إلى تناظرية واحدة للموضوع إلى ngOnChanges: Subject<SimpleChanges>
لا يزال بإمكانك التصفية والتعيين لمدخل واحد محدد فقط إذا كنت تريد ذلك.

1 يبدو الموضوع لكل إدخال كثيرًا دون التحدث عن حذف خاصية فئة لإنشاء أداة إنشاء وسيط وأن نوع الإدخال الخاص بك خاطئ وأن تنفيذ input = value سيؤدي في الواقع إلى إصدار القيمة على ما يمكن ملاحظته وأنت لست كذلك استكمال موضوعك.

يمكنك العثور على مثال تطبيقي لفكرتي هنا ، نهج المصمم تجريبي ولكني أعتقد أنه يجب أن يكون استخدام نهج الوراثة آمنًا جدًا (ضع في اعتبارك أنني فعلت ذلك الآن لتظهر هنا ، لم يتم استخدامه).

ghetolay لا يهم ما إذا كان الموضوع قد اكتمل ، عند إغلاق العرض ، لا توجد اشتراكات أخرى في الدفق ويمكن التخلص منها بواسطة GC. إصدار القيمة على ما يمكن ملاحظته هو أساسًا الهدف من هذا. لا يتحقق المترجم الزاوي حاليًا من أنواع خصائص الإدخال ، ونأمل أنه بحلول الوقت الذي يفعل فيه شيئًا أكثر رسمية سيكون متاحًا ؛)

changes$ بتسريب واجهة BehaviorSubject إلى المكون ، من الناحية المثالية يجب كتابته على أنه Observable<...> ، بخلاف ذلك يبدو معقولًا ، إذا كان أكثر تفصيلاً.

بالنسبة لموضوع العديد من الموضوعات ... سواء كنت تستخدم n مواضيع أو 1 فلا يزال لديك اشتراكات n . عندما يكون لديك موضوع واحد ، ينتهي بك الأمر بإضافة مشغل خرائط واحد وعامل تصفية واحد لكل اشتراك ، فلن يكون الحمل الإضافي لهذا الأمر أقل بكثير من مجرد استخدام مواضيع n ، بل قد يكون أسوأ.

بتجاهل كتابة معلمات الإدخال نفسها ، يوفر الإصدار المستند إلى المصمم واجهة برمجة تطبيقات أكثر أمانًا لمستهلكي العناصر المرئية من الأنواع SimpleChange القائمة على any .

تضمين التغريدة

عندما يتم إغلاق العرض ، لا توجد اشتراكات أخرى في الدفق ويمكن التخلص منها بواسطة GC

أنت تفترض أن جميع الاشتراكات ستكون مرتبطة بالعرض وستحصل على نفس دورة حياة العرض. أنا لا أفترض أي افتراض حول كيفية استهلاك المرصد.

إصدار القيمة على ما يمكن ملاحظته هو أساسًا الهدف من هذا. لا يتحقق المترجم الزاوي حاليًا من أنواع خصائص الإدخال ، ونأمل أنه بحلول الوقت الذي يفعل فيه شيئًا أكثر رسمية سيكون متاحًا ؛)

قصدته للمستخدم ، لا يزال بإمكان المستخدم الوصول إلى الخاصية وتعيينها. لذلك ، سيتم تعيين الخاصية كما لو كانت رقمًا باستثناء كتابتها على أنها قابلة للملاحظة ولن يؤدي هذا إلى تعيين الخاصية مطلقًا بل يجعلها تنبعث. هذا محير للغاية بالنسبة لي.

بالنسبة لموضوع العديد من المواضيع ... سواء كنت تستخدم n مواضيع أو 1 لا يزال لديك عدد n من الاشتراكات. عندما يكون لديك موضوع واحد ، ينتهي بك الأمر بإضافة مشغل خرائط واحد وعامل تصفية واحد لكل اشتراك ، فلن يكون الحمل الزائد لهذا الأمر أقل بكثير من مجرد استخدام موضوعات n ، بل قد يكون أسوأ.

لن أخوض في هذا النوع من النقاش هنا لأننا سرعان ما نفقد التركيز على الهدف الرئيسي.

لقد قمت بالتحديث لعدم كشف Subject وقمت ببناء شيء لإضافة الكتابة إلى التغييرات.
أنا لا تستخدم BehaviorSubject ولكن سهل Subject لأنني لا نرى تلك الملحوظة كحامل قيمة ولكن مع تغير مع مرور الوقت.
لقد وجدت خللاً للتو: عند استخدام الأنبوب غير المتزامن ، لا تنبعث القيمة الأولى لأن الأنابيب غير المتزامنة ستشترك بعد أول إصدار. سوف أقوم بتحديث الكود الخاص بي لاحقًا للتعامل مع هذه الحالة بشكل صحيح.

ها هو الرابط مرة أخرى: https://stackblitz.com/edit/angular-observableinput؟file=observablechanges٪2Fimpl.ts

أنت تفترض أن جميع الاشتراكات ستكون مرتبطة بالعرض وستحصل على نفس دورة حياة العرض. أنا لا أفترض أي افتراض حول كيفية استهلاك المرصد.

حسنًا ، أرى وجهة نظرك ، سيؤدي إكمال العناصر المرئية إلى إغلاق جميع الاشتراكات ، لكنه ليس شيئًا يقلقني حقًا. في تطبيقنا ، تحدث 99٪ من الاشتراكات من خلال الأنبوب غير المتزامن وفي الحالات القليلة التي لا يتعين إغلاقها يدويًا على أي حال لأنها غالبًا ما تكون مصدرها في مراقبات خارجية مصدرها Redux / إلخ من خلال combLatest / switchMap.

لن أخوض في هذا النوع من النقاش هنا لأننا سرعان ما نفقد التركيز على الهدف الرئيسي.

حسنًا ، لقد وجهت نقدًا غير صالح لذلك كان من الضروري مواجهته.

~ أيضًا استخدام فصلك من خلال الوراثة لن يعمل ، فإن الكود الذي تم إنشاؤه بواسطة مترجم AOT لا يستدعي أساليب دورة الحياة في الفئات الرئيسية ، راجع https://github.com/angular/angular/issues/12756#issuecomment -260804139 ، أنت سأحتاج إلى إضافة ngOnDestroy() { super.ngOnDestroy() } وآخر مقابل ngOnChanges لجميع المستهلكين في الفصل. ~ <- يبدو أنه تم إصلاحه اعتبارًا من Angular 4.4 مع بعض القيود.

لقد راجعت قلقي بشأن استخدام الأنبوب غير المتزامن وبما أنه لا يزال بإمكانك الوصول إلى المدخلات ، فلا أعتقد أن الاستخدام كان منطقيًا. إذا كنت ترغب فقط في ربط قيمة الإدخال في القالب ، يمكنك فقط الارتباط مباشرة بالإدخال دون الحاجة إلى استخدام أي شيء يمكن ملاحظته وغير متزامن هنا. إذا كنت ترغب في تكوين عنصر جديد يمكن ملاحظته منه ، فيجب أن تكون قادرًا على الحصول على ما تريده بالضبط بسهولة (ربما باستخدام startWith مكان ما).

لذلك أعتقد أن بياني السابق لا بأس به:

أنا لا أستخدم BehaviorSubject بل موضوعًا عاديًا لأنني لا أرى هؤلاء الذين يمكن ملاحظتهم بصفتهم صاحب قيمة ولكن كتغييرات بمرور الوقت. إذا كنت بحاجة إلى الوصول إلى قيمة إدخال ، فلا تزال الخاصية موجودة ويمكنك الرجوع إليها بشكل متزامن.

هذا الرمز تجريبي للغاية ، إنه مجرد نوع من أنواع poc وقد لعبت به فقط على هذا المكدس.
لذلك لم يكن يجب أن أقول إنه كان آمنًا للغاية آسف وقد لا يعمل مع AOT كما ذكرت.
لقد جربته للتو وكلا الأسلوبين يعمل حاليًا مع AOT (الزاوي v4.3.6 ، cli v1.4.1).

نقطتي الرئيسية هنا هي أن الانتقال من changes يمكن ملاحظته والذي يحتوي على جميع تغييرات المدخلات يمنحك إمكانية القيام بأي شيء تحتاجه باستخدام عوامل التشغيل: الرد عند تغيير أي إدخال ، عند تغيير إدخال واحد فقط ، عند وجود عدد تعسفي من المدخلات تغيرت ، عندما تغيرت من قيمة معينة إلى أخرى ، إلخ ...
يمكنك تكوين ما تريده الذي يمكن ملاحظته.

يوجد أيضًا موضوع واحد فقط يمكن إدارته من أجل التنفيذ وخاصية واحدة للاستخدام للمستخدم مقابل 1 لكل إدخال.

الشيء الذي يمكنني تغييره هو إصدار قيم جديدة فقط وليس كائن SimpleChanges حيث يمكن للمستخدم على الأرجح استخدام pair و map للحصول على نفس النوع من البنية مثل SimpleChange . ولكن ما حصلنا عليه حاليًا هو SimpleChanges لذا سيكون من السخف تحليله لمجرد إعادة تكوين شيء مشابه لاحقًا.

ملاحظة:

حسنًا ، لقد وجهت نقدًا غير صالح لذلك كان من الضروري مواجهته.

غير صالح لك .

إنها ليست وجهة نظر شخصية عندما نشير إلى الأداء ، فهذه حقائق موضوعية قابلة للقياس. تشعر أن 3 مواضيع تساوي عبءًا أكبر من 6 عوامل إضافية ، بالتأكيد ربما تكون على حق ولكن لا يوجد أساس منطقي للاعتقاد بذلك حتى تقوم ببعض القياسات.

فيما يتعلق بالتفاعل مع العديد من المدخلات ... بالتأكيد يمكنك فقط استخدام switchMap أو دمج أحدث أو أي من المشغلين الآخرين المصممين للعمل مع العديد من الملاحظات. أنت تدلي ببيانات جريئة وواسعة للغاية حول هذا الموضوع ، إذا كنت تريد حقًا متابعة هذه المحادثة ، فلنخرجها من أداة تعقب هذه المشكلة.

إليك إصدار به عيوب ومزايا مختلفة ولكنه يتطلب فئة أساسية:

import { OnChanges, OnDestroy, SimpleChanges } from '@angular/core'
import { BehaviorSubject } from 'rxjs/BehaviorSubject'
import { Observable } from 'rxjs/Observable'
import 'rxjs/add/operator/map'
import 'rxjs/add/operator/distinctUntilChanged'

export class ChangeObserver implements OnChanges, OnDestroy {
  protected ngChanges = new BehaviorSubject<object>({})

  ngOnChanges(changes: SimpleChanges) {
    const props = { ...this.ngChanges.value }
    for (const propName in changes) {
      props[propName] = changes[propName].currentValue
    }
    this.ngChanges.next(props)
  }

  ngOnDestroy() {
    this.ngChanges.complete()
  }

  changes<K extends keyof this>(key: K): Observable<this[K]>
  changes<V>(key: string): Observable<V>
  changes(key: string) {
    return this.ngChanges.map(props => this.ngChanges.value[key]).distinctUntilChanged()
  }
}

وللاستخدام:

class MyComponent extends ChangeObserver {
  @Input() public field: string
  // typescript knows this is Observable<string>
  field$ = this.changes('field')

  @Input() private privField: number
  // typescript can't access private stuff from outside the class so we need to help it out
  privField$ = this.changes<number>('privField')
}

لست متأكدًا مما إذا كنت قد أسأت فهم المشكلة ، لكن ألا يحل الأنبوب غير المتزامن هذه المشكلة؟
[inputVar]="observableValue | async" ..

najibla لقد أسأت فهمك ، المدخلات ليست ملحوظة ، لذا فإن الأنبوب غير المتزامن لا يساعد.

ohjames حسنًا في حالتي ، لقد نجح باستخدام الأنبوب غير المتزامن من أجل ملاحظة. وعندما أقوم بتحديث القيمة التي يمكن ملاحظتها من الأصل ، تنعكس القيمة في المكون الفرعي.

najibla تدور مشكلة github هذه حول تحويل خصائص @Input إلى أشياء يمكن ملاحظتها ، وهذا مرتبط بشكل وثيق بالحالة التي تصفها.

على سبيل المثال ، لن تحتاج إلى تحويل خصائص الإدخال إلى خصائص يمكن ملاحظتها في طريقة العرض ، سواء كان المكون يستجيب لتغير خاصية الإدخال باستخدام عنصر يمكن ملاحظته أم لا يجب عزله في المكون نفسه. بخلاف ذلك ، عليك تغيير واجهة المكون الخاص بك إذا قررت استخدام خاصية باعتبارها خاصية يمكن ملاحظتها والتي تتعارض مع نهج الزاوية المعتاد "المرئي أولاً".

icepeng في الواقع ، لم

<app-child [prop]="prop$ | async"></app-child>

... ثم يوفر طريقة للوصول إلى prop داخل AppChildComponent كملف يمكن ملاحظته على الرغم من أنه لا يمكن ملاحظته (أو إذا كان يمكن ملاحظته ، فستحصل على ما يمكن ملاحظته ). الآن بالطبع إذا كان لديك prop$ في المقام الأول كما في المثال الخاص بك ، فقد لا يبدو ذلك منطقيًا (يمكنك بالفعل تمرير ما يمكن ملاحظته باستخدام المدخلات الآن). ومع ذلك ، فإنه يوفر الكثير من القيمة عندما يكون الإدخال الذي تم تمريره غير قابل للملاحظة بالفعل (على سبيل المثال ، index من ngFor ).

تكمن مشكلة تمرير مُدخل يمكن ملاحظته (وهو أمر ممكن تمامًا الآن) في أنه لن يعمل تمامًا مع OnPush .

fxck حسنًا ، أنت محق في أنه لن يتم استدعاء ngOnChanges عندما يصدر المرصد (لأن الإدخال يظل كما هو) ، ولكن طالما أنك تستخدم الأنبوب غير المتزامن للاشتراك في أمر يمكن ملاحظته يمر عبر @Input سيعمل OnPush بشكل جيد لأن الأنبوب غير المتزامن يقوم يدويًا بتشغيل كاشف تغيير المكون الفرعي.

نعم ، لقد تم توجيهه نحوicepeng.

ohjames fxck لم أكن أعرف أن تمرير ما يمكن ملاحظته ممكن الآن ، آسف للمعلومات الخاطئة.

نظرًا لأن التمرير المباشر الذي يمكن ملاحظته أمر ممكن ، فأنا لست متأكدًا من أن @ObserveInput سيكون مفيدًا.
أعتقد أنه إذا كانت القيمة التي يمكن تغييرها غير قابلة للرصد ، فهذه مشكلة بالفعل.
مجرد رأي شخصي.

icepeng ضع في اعتبارك هذا:

<ng-container *ngFor="value in (values$ | async); let i = index">
  <child-component [value]="value" [index]="i"></child-component>
</ng-container>

كيف تجعل index قابلاً للاستهلاك كقابل يمكن ملاحظته هنا دون القفز عبر الأطواق؟

أو ضع في اعتبارك أيضًا أنك تكتب مكتبة تابعة لجهة خارجية ولا تريد إجبار مستهلكي مكتبتك على تمرير العناصر التي يمكن ملاحظتها إلى المكون الخاص بك (لا يشعر العديد من المستخدمين بالراحة مع التدفقات ويتجنبون rxjs).

هناك العديد من الحالات الأخرى التي يكون فيها هذا مفيدًا.

ohjames index ستكون قيمة ثابتة لكل child-component ، لذلك لا أعتقد أنه يجب ملاحظتها. ومع ذلك ، فهمت الآن لماذا يريد الناس هذه الميزة. ويبدو الحل الخاص بك جيدًا لكتابة مكتبة طرف ثالث.

يبدو أسلوب BehaviorSubject أفضل ، وسيكون رائعًا إذا قدم Angular core @NgChanges() مصممًا من هذا القبيل.

{
  @NgChanges() ngChanges$: BehaviorSubject<{ prop: string }>
  @Input() prop: string;

  ngOnInit() {
    this.ngChanges$.subscribe(changes => console.log(changes.prop));
  }
}

هل هذا ممكن للتنفيذ؟

يفضل استخدام ReplayObservable مع طول المخزن المؤقت 1 ، فلا حاجة إلى دلالات قيمة BehaviourSubject عندما يكون لديك أيضًا إمكانية الوصول إلى الخاصية.

بالنسبة إلى ما إذا كان من الممكن التنفيذ ، تحقق من سجل المشكلة للعديد من عمليات التنفيذ والخيارات المختلفة. لا شيء رائع وبعضها معطل تمامًا ، للقيام بذلك بشكل صحيح نحتاج إلى العلاقات العامة المرتبطة أو شيء مشابه.

سنتان: نظرًا لأن object.observe تم إهمال قيمته لصالح الوكلاء ، كان الحل هو تمديد وكيل (نعم لا يمكنك أن أعرف ، سبب إعادته من المُنشئ) ثم الاستماع إلى أي مفتاح ينتمي إلى هذا يمكن ملاحظته من خلال طريقة $ get (keyName). يمكنك استخدامه مع أي كائن ، وليس فقط فئة واحدة.

import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';

/**
 * Extends this class to be able to observe any key affectation
 */
class ObservableProxy {
    private changes: Subject<[PropertyKey, any]> = new Subject<[PropertyKey, any]>();

    constructor() {
        return new Proxy(this, {
            set: (object, key, value) => {
                this.changes.next([key, value]);
                object[key] = value;
                return true;
            }
        });
    }

    public $get<K extends keyof this>(key: K): Observable<this[K]> {
        const value: this[K] = this[key];

        const startWith: Observable<this[K]> = Observable.of(value)
            .filter((initialValue) => // remove this filter if you dont mind receiving an undefined value on subscription
                initialValue !== undefined;
            );

        return this.changes
            .filter(([changedKey]) => {
                return changedKey === key;
            })
            .map(([changedKey, nextValue]) => nextValue)
            .merge(startWith);
    }
}

مثال:

class User extends ObservableProxy {
public name: string;
}

const user: User = new User();
user.$get("name").subscribe((value)=> {
console.log(value);
})

user.name = "toto"; // prints console.log("toto")

robwormald ، هل هناك أي

bryanrideshark إن أفضل فرصة لدعم ذلك هي من خلال https://github.com/angular/angular/issues/10185 على ما أعتقد ، مندهشًا من أن العلاقات العامة ليست مرتبطة بهذه المشكلة.

لن يحدث هذا إلا بعد أن نقوم بشحن Ivy
يوم الأربعاء 21 فبراير 2018 الساعة 7:56 صباحًا كتب James Pike [email protected] :

bryanrideshark https://github.com/bryanrideshark أفضل فرصة
يتم دعم هذا من خلال # 10185
https://github.com/angular/angular/issues/10185 أعتقد ، فاجأ ذلك
العلاقات العامة ليست مرتبطة بهذه القضية.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/angular/angular/issues/5689#issuecomment-367372931 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AAgpkvtGA4w8uHgiz0QsdYwBgqgM2EpAks5tXDyWgaJpZM4Gwr8f
.

لغتك الإنجليزية رائعة وزاويتك أكبر.

@ pldin601 طريقتك لا تدعم كود observable-input الخاصة بي بدلاً من ذلك والتي تعمل بشكل جيد مع AOT.

@ pldin601 تكمن مشكلة الكود في أنه يضيف طريقة دورة حياة ngOnDestroy ديناميكيًا. يستدعي الكود المترجم AOT ngOnDestroy إذا كان بإمكان المترجم أن يستنتج وجوده بشكل ثابت. لذلك لن تعمل طريقتك إلا إذا كان كل مكون يستخدم المصمم يحدد أيضًا ngOnDestory (يمكن أن يكون فارغًا إذا لم يكن هناك حاجة). في جميع الحالات الأخرى ، سيؤدي إلى تسريب الاشتراكات ، مما يمنع المكونات من جمع القمامة.

أعتقد أن هذا سيحدث بعد اكتمال القسم 3.2 (ونأمل أن تؤخذ هذه الحاجة في الاعتبار)؟
https://is-angular-ivy-ready.firebaseapp.com/#/status

هل سيكون Ivy جزءًا من 7.0.0؟

لقد قمت بتنفيذ مصمم ديكور يمكنه ربط خاصية بممتلكات مصاحبة يمكن ملاحظتها. يمكن استخدامه في خصائص الإدخال الزاوي ، ولكن أيضًا في أي خاصية أخرى. إنه مستوحى من المصمم @ObservableInput() للديكور ohjames ، ولكنه يتجنب المشاكل المحتملة التي يسببها عدم تطابق النوع بين حاصل على الممتلكات والمحددات باستخدام خاصية مختلفة لتوفير Observable.

https://github.com/PSanetra/bind-observable

مثال:

class MyClass {

  @BindObservable()
  public myProp: string = 'initialValue';
  public myProp$!: Observable<string>;

}

const myInstance = new MyClass();

myInstance.myProp$.subscribe(console.log);

myInstance.myProp = 'newValue'

يقوم هذا الرمز بطباعة القيم 'initialValue' و 'newValue' إلى وحدة التحكم.

أي تحديث حول موعد إصدار هذا حتى الآن تبدو الحزمة observable-input الأكثر أناقة دون كسر أي شيء + عدم وجود فئة فرعية. ohjames ما مدى استقرار / اختبار جيد في هذه المرحلة؟

أعتقد أن الدعم الرسمي سيكون أكثر نضجًا ، وسيضمن دعمًا مستمرًا عبر الإصدارات وتجربة مطور أكثر سلاسة / سيشجع المطورين على الانتقال إلى rxjs * والتحسين مع اكتشاف تغيير الدفع (يجب أن تكون هذه ميزة أساسية في رأيي)

* بدون المساومة على التوافق مع المدخلات التي لا يمكن ملاحظتها أو الحاجة إلى نموذج معياري إضافي للمدخلات الهجينة ، على سبيل المثال: استدعاء المُحدد التالي على الموضوع

تستخدم المدخلات القابلة للملاحظة في الزاوية 4 و 5 و 7 مع وبدون aot. يبدو انه يشتغل جيدا. أنا متأكد من أنني كنت أعرف بشكل غامض ما كنت أفعله عندما كتبته.

آمل أن يضيفوه في إطار العمل ويشجعوا استخدامه ، لا يكفي التنزيلان الأسبوعيان npm مقارنة بالمزايا التي يقدمها xD إذا قاموا بإضافته ، أراهن أن الناس سيرون أنه من السهل اتباع هذا النهج

أقترح واجهة برمجة التطبيقات التالية للإدخال غير المتزامن مع تعريف المستخدم observer

decalre function AsyncInput(bindName?:string) : <T extends Observer>(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<T>) => any

يمكن للمستخدمين استخدامه كملف

@AsyncInput()
asynchronusProperty1 = new Subject();

@AsyncInput()
asynchronusProperty2 = new ReplySubject(1);

@AsyncInput()
asynchronusProperty3 = new UserObserver(); // where UserObserver implement `Observer` interface

يمكن للزاوية الداخلية استدعاء observer.next(newValue) كلما تغيرت القيمة.

لا تنس دعم @HostBinding أيضًا!

يجب أن يتم دمج هذا مع حقنة constructorInput لجعلها أكثر روعة. بهذه الطريقة يمكننا إصلاح "التهيئة الصارمة للعقارات" بطريقة أنيقة للغاية:

class MyComponent {
  inputData$: Observable<Data>;
  constant: string;

  constructor(
    @Input() inputData$: Observable<Data>,
    @Input() constantString: string
  ) {
    this.inputData$ = inputData$;
    this.constant = constantString;
  }

}

benneq جدير بالذكر أنه يمكن أن يكون صغيرًا مثل:

class MyComponent {
  constructor(
    @Input() private inputData$: Observable<Data>,
    @Input() private constantString: string,
  ) {}
}

@ maxime1992 نعم ، على الرغم من أنك ستحتاج إلى مصمم منفصل للمدخلات

benneq @ maxime1992 أسماء المعلمات ليست جزءًا من البيانات الوصفية

@ trotyl أعتقد أنه يمكنك بعد ذلك استخدام @Input('paramName') private myParam: Observable<Data>

@ trotylbenneq نعم بلدي سيئة. لا تهتم: zipper_mouth_face:

لا أعرف ما إذا كان شخص ما قد نشر هذا الحل بالفعل ولكن هذا حل جيد إلى حد ما

ElianCordoba هذا ليس عن HTML <input> . إنه حول الزاوي @Input()

هذه مشكلة مختلفة ولكنها مؤلمة بالمثل ElianCordoba. https://github.com/angular/angular/issues/13248

أعتقد أن هذا مطلب زائف. أولاً ، يمكن لمصمم الإدخال قبول قيمة نوع يمكن ملاحظتها ، وثانيًا ، إذا كان المكون يتطلب عنصرًا يمكن ملاحظته كمدخل ، فيجب أن يتم طرح الخطأ بشكل صريح عند تلقي قيمة غير ملحوظة بدلاً من تحويلها بهدوء إلى قيمة نوع يمكن ملاحظتها.

إنه مشابه تمامًا لتحويل النوع الضمني في جافا سكريبت ، وقد يتم الخلط بينه وبين التسبب في حدوث خلل ويصعب العثور عليه.

هذا لا يتعلق بإسكات المدخلات الخاطئة. يتعلق الأمر بتعريض واجهة مشتركة عبر المكونات (وهي مدخلات غير ملحوظة). يمنحك هذا حرية تقديم وظيفة rx دون كسر واجهتها في العالم الخارجي. فائدة أخرى هي رفع قابلية التغيير والحالة الداخلية بشكل أساسي لأن كل شيء سيكون بمثابة تحول في المدخلات مما يجعل اكتشاف تغيير الدفع من تلك النقطة فصاعدًا أمرًا لا يحتاج إلى تفكير.

على العكس من ذلك ، فإن التعريض ، وهو واجهة تتطلب الأصوات التي يمكن ملاحظتها تبدو ثقيلة وتجبر الناس على تقديم (قيمة) لمجرد أن المكون الخاص بك قال ذلك يبدو غريبًا بالنسبة لي.

بالإضافة إلى أنها لا تتعلق بالتحويل الصامت ، إنها واجهة برمجة تطبيقات للاشتراك في التغييرات عبر rxjs. بالنظر إلى angular.http وجهاز التوجيه يوفران الملاحظات ، فمن المحرج للغاية أن معالجة تغيير الإدخال لا تفعل ذلك ، فإن توحيد عوالم الاسترجاعات و RxJs يتطلب الكثير من لوحة الغلاية.

لا يعني ذلك أنني لا أحب بعض الحلول الذكية المذكورة أعلاه ، ولكن في بعض الأحيان مجرد إعادة تنظيم طفيفة للطريقة "القياسية" للقيام بذلك يكفي لحل المشكلة الحقيقية هنا وهي الافتقار إلى الوضوح / الحماقة. بالإضافة إلى أنني ما زلت آمل في طريقة "رسمية" لما بعد اللبلاب للقيام بذلك يومًا ما.

@Input('isOuterPanel')
set isOuterPanel(value: CheckoutPanelHeaderSettings)
{
    this.inputs.outerPanel$.next(value);
}

@Input('config')
set config(value: CheckoutPanelHeaderSettings)
{
    this.inputs.config$.next(value);
}

// observables for <strong i="6">@Inputs</strong>
inputs = {
    config$: new BehaviorSubject<CheckoutPanelHeaderSettings>(1),
    outerPanel$: new BehaviorSubject<CheckoutPanelHeaderSettings>(1)
};

ثم يمكنك فقط وضع شيء مثل combineLatest(this.service.magicInput$, this.inputs, config$)...... لدمج المدخلات مع RxJS.

إما BehaviorSubject أو ReplaySubject يعمل. السلوك عادة ما يكون الموضوع أكثر أمانًا ويمكن التنبؤ به.

  • BehaviorSubject - استخدمه إذا كان لديك افتراضات
  • ReplaySubject - يمكن ملاحظته لن ينبعث إذا نسيت تعيين قيمة الإدخال

هذا لا يساعد فقط في وضوح الكود ولكن لأنني أقوم بتجميع جميع المدخلات معًا ، يمكنني بسهولة رؤية ما هو الإدخال "النقي" الذي يمكن ملاحظته بمجرد كتابة this.inputs. والحصول على الإكمال التلقائي.


يمكنك المضي قدمًا في استخدام نوع الأمان باستخدام هذا (غالبًا ما يكون هذا من أجل المتعة فقط).

// define this globally to 'unwrap' a property 'inputs' with an object of ReplaySubject / BehaviorSubject
export type InputTypes<T extends { inputs: { [key: string]: ReplaySubject<any> | BehaviorSubject<any> } }> = {
    [P in keyof T['inputs']]: T['inputs'][P] extends Observable<infer X> ? X : unknown;
}
// define a local 'InputType' helper above each component
type InputType = InputTypes<CheckoutSmartHeaderComponent>;

ثم لا تحتاج إلى تحديد نوع خاصية Input بشكل صريح .

@Input('config')
set config(value: InputType['config$'])
{
    this.inputs.config$.next(value);
}

كان بإمكاني إنشاء واجهة ObservableInputs للمكون لفرض inputs لكنني قررت عدم القيام بذلك لأنه لن يتم التجميع على أي حال إذا قمت بإفساد هذا الأمر.

تضمين التغريدة

قررت أن أضع مصمم الديكور الخاص بي هناك. إنها حزمة npm الأولى الخاصة بي لذا أنا متأكد من أن هناك شيئًا ما مفقودًا ، ولكن ها هو: https://www.npmjs.com/package/@ng-reactive/async -input

التركيب

npm install @ng-reactive/async-input --save

إستعمال

import { Component, Input } from '@angular/core';
import { AsyncInput } from '@ng-reactive/async-input';
import { BehaviorSubject } from 'rxjs';

@Component({
  selector: 'app-hello',
  templateUrl: './hello.component.html',
  styleUrls: ['./hello.component.css']
})
export class HelloComponent {
  @Input() name: string;
  @AsyncInput() name$ = new BehaviorSubject('Default Name');

  constructor() {
    this.name$.subscribe(name => console.log('from async input', name));
  }
}

@ mfp22 رائع حقًا ، لا أرى أي سبب لعدم

https://github.com/mfp22/async-input/tree/master/projects/async-input

أرى أن هذه مشكلة قديمة جدًا ، لكن الميزة مذهلة جدًا وقد خرجت حقًا من رؤيتها في Angular.

ما هو أكثر برودة هو أنه مع المدخلات التي يمكن ملاحظتها ، لا تحتاج إلى خطاف OnChanges - يمكنك استخدام عامل التشغيل pairwise rxjs للحصول على القيم السابقة والحالية للمدخلات التي يمكن ملاحظتها:

@Component({...})
class MyReactiveComponent {
  @ObservableInput() prop: Observable<string>; // Whatever syntax may be...

  // emits [prevValue, currValue] and no OnChanges hook yay!!
  propChanges$ = this.prop.pipe(pairwise());
}

https://github.com/rx-ts/ngrx/blob/master/src/utils/decorators.ts#L56 -L124

إنه تطبيقي الشخصي ، إنه يعمل بشكل مثالي ورائع جدًا ، إذا كان بإمكاننا تركيبه ، فهذا رائع حقًا.

لقد قمت بنشر الحل الذي استخدمته شخصيًا في مشاريعي كحزمة npm:

https://github.com/futhark/ngx-observable-input

التركيب

npm install ngx-observable-input

إستعمال

...
<image-item [url]="currentImageUrl"></image-item>
import { Component, Input } from "@angular/core";
import { ObservableInput } from "ngx-observable-input";
import { Observable } from "rxjs";

@Component({
    selector: "image-item",
    template: `<img [src]="url$ | async" />`
})
export class GalleryComponent {
    @ObservableInput() @Input("url") public url$: Observable<string>;

    ...
}

أرى أن هذه مشكلة قديمة جدًا ، لكن الميزة مذهلة جدًا وقد خرجت حقًا من رؤيتها في Angular.

ما هو أكثر برودة هو أنه مع المدخلات التي يمكن ملاحظتها ، لا تحتاج إلى خطاف OnChanges - يمكنك استخدام عامل التشغيل pairwise rxjs للحصول على القيم السابقة والحالية للمدخلات التي يمكن ملاحظتها:

@Component({...})
class MyReactiveComponent {
  @ObservableInput() prop: Observable<string>; // Whatever syntax may be...

  // emits [prevValue, currValue] and no OnChanges hook yay!!
  propChanges$ = this.prop.pipe(pairwise());
}

هذه مشكلة كانت تزعجني أيضًا لفترة من الوقت ، لذلك قمت بالتحقيق قليلاً وتوصلت إلى نفس الحل الذي ذكرته هنا (gund).

لقد قمت بتطبيق مساعد ديكور صغير ( @ObservableInput ) يمتد داخليًا إلى @Input Decorator ويسمح بهذا النوع من التكوين. يمكنك التحقق من ذلك هنا (أيضًا كحزمة npm ). لقد كنت أختبرها بأمثلة بسيطة ، لكن لم يكن لدي الوقت لاستخدامها في المشاريع الممتدة. نرحب بأي ملاحظات :)

هنا مثال على الاستخدام:

@Component({
  selector: 'app-test',
  template: `<span>{{ message$ | async }}</span>`
})
class TestComponent {
  @ObservableInput<number>('price') price$: Observable<number>;
  @ObservableInput<string>('name') name$: Observable<string>;

  message$ = combineLatest(this.price$, this.name$).pipe(
    map(([price, name]) => `${name} costs {price}`)
  );
}

ويمكن استخدام هذا المكون على النحو التالي:

<app-test [price]="price"
          [name]="name">
</app-test>

aleics هل أنت متأكد من أن هذا سيعمل مع مترجم AOT؟

aleics هل أنت متأكد من أن هذا سيعمل مع مترجم AOT؟

لا ، ليس خارج الصندوق ، بالطبع ، لأن الخاصية @Input لم يتم تعريفها بشكل صريح. ولكن يمكنك تحديد الوحدة الخاصة بك بـ CUSTOM_ELEMENTS_SCHEMA ، كما هو الحال عند استخدام مكونات الويب ، ومن ثم يجب تجميعها.

هذا العدد مفتوح منذ 5 سنوات 🤦‍♂. أعتقد أنه من الضروري الحصول على هذا لتسهيل نهج البرمجة التفاعلية

آيفي هنا أخيرًا ، لذا أعتقد أن شخصًا ما لديه الوقت للعمل على هذا؟ من فضلك من فضلك من فضلك!

يا إلهي أنا أوافق على أن هذا مطلوب بشدة. يجب أن تنبعث بيانات الإدخال كمصدر تفاعلي ، ويجب عليك استخدام الحل البديل لجعل ذلك يعمل في ngOnChanges

حقا أتطلع لهذا

أدرك أن Angular مفتوح المصدر ، ولكن هل من الخطأ أو السذاجة بالنسبة لي أن أعتقد أن مشروعًا تديره Google يجب أن يكون قادرًا على حل المشكلات التي تم تمييزها بنجمة بشكل كبير والمطلوبة في أقل من 5 سنوات؟ هل هناك بعض المشكلات المالية التي لست على علم بها والتي تمنع Google من توظيف المزيد من المطورين للعمل على Angular؟

@ etay2000 لا أعرف ، أعتقد أنه من المضحك كيف يمكنك القيام بـ 75٪ من الأشياء في Angular باستخدام rxjs ثم لشيء أساسي وشائع الاستخدام كمدخلات مكونة ، وفجأة أجبرت على الانخراط في الإجراءات العالمية. لطالما حصلت على هذا الجزء المهم من مشروعك الذي لا يمكن أن يعمل مع عالم الملحوظات ، لذلك فأنت دائمًا مجبر على استخدام اللوح المعياري لإعادة لصقها معًا مرة أخرى. لا يمكنك أبدًا تحقيق نهج وظيفي بالكامل لمشروعك. لذا فإن هذه القضية التي ظلت مفتوحة لمدة 4 سنوات تذكرني بنقص البراغماتية التي دفعتني بعيدًا عن Angular وإلى أطر أخرى ، لأنها مفيدة جدًا. إذا كنت ترغب في استخدام rxjs لكل شيء ، فربما يكون cycle.js هو الحل الأفضل ، وإذا كنت لا تريد أن تضطر إلى استخدام rxjs على الإطلاق ، فربما يكون Vue كذلك. إن الاضطرار إلى استخدام العناصر القابلة للملاحظة نصف الوقت وعدم القدرة على استخدامها في النصف الآخر لا معنى له. إن دمج تجريد قوي للغاية مع منحنى تعليمي عالٍ ثم فشل في دمجه بالكامل هو مجرد أمر محير.

أشعر أن سلسلة تحديد الأولويات تسير على هذا النحو

متطلبات مستخدمي Google الداخليين -> أي شيء يتعلق بكون المترجم أسرع -> أي شيء يتعلق بحجم التطبيق أصغر -> أي شيء لا يزعج القادمين الجدد -> ما يريده المطورون بالفعل

وعلى الرغم من أن العملاء المحتملين التقنيين قد يقولون إنهم يتفقون على أهمية ذلك ، فإن الحقيقة هي أن إيغور وميسكو يميلون إلى التفكير في معظم المشكلات من حيث تجميع القوالب وعرض عمليات الربط والعرض. بغض النظر عما يقوله مستهلكو Angular إنه مهم بالنسبة لهم ، فإن الحل دائمًا هو تغيير نظام القوالب ، أو كتابة عارض جديد ، أو جعل المترجم أفضل.

المصدر: https://medium.com/@jeffbcross/jeffs-letter-to-the-angular-team-and-community-5367934a16c9)

ما عليك سوى إلقاء نظرة على بعض أكثر القضايا التي حظيت بالتأييد.

الاقتراح: الإدخال كما يمكن ملاحظته # 5689

تم إنشاؤه منذ 5 سنوات ، وآخر رد من أحد أعضاء الفريق ذي الصلة - منذ 5 سنوات ، والوضع الحالي غير معروف.

دعم تيارات الأحداث الباردة في القوالب رقم 13248

تم إنشاؤه منذ 4 سنوات ، الرد الأخير من أحد أعضاء الفريق ذي الصلة - منذ عام واحد ، الوضع الحالي - في انتظار وصول Ivy.

الاقتراح: توفير خطافات دورة حياة المكون على أنها عناصر ملحوظة # 10185

تم إنشاؤه منذ 4 سنوات ، وآخر رد من أحد أعضاء الفريق ذي الصلة - منذ 3 سنوات ، والوضع الحالي غير معروف.

الاقتراح: الحاجة إلى القدرة على إضافة توجيهات إلى عناصر المضيف في إعلان المكون. # 8785

تم إنشاؤه منذ 4 سنوات ، وآخر رد من أحد أعضاء الفريق ذي الصلة - منذ عامين ، والوضع الحالي غير معروف.

as local-val بدون * ngIf # 15280

تم إنشاؤه منذ 4 سنوات ، وآخر رد من أحد أعضاء الفريق ذي الصلة - منذ عامين ، والوضع الحالي غير معروف.

دعم عرض المحتوى الديناميكي # 8563

تم إنشاؤه منذ 4 سنوات ، وآخر رد من أحد أعضاء الفريق ذي الصلة - منذ 3 سنوات ، والوضع الحالي غير معروف.

المحتوى الافتراضي ng-content # 12530

تم إنشاؤه منذ 4 سنوات ، وآخر رد من أحد أعضاء الفريق ذي الصلة - أبدًا ، الوضع الحالي غير معروف.

ثم هناك أشياء مثل ميزات المكونات ، والتي من شأنها أن تسمح بمكونات ذات ترتيب أعلى ، ثم هناك بالطبع العديد من المشكلات الأكثر تم التصويت عليها ، ولكن كنت آمل أن تتم معالجتها (أي ، معالجتها ، وليس بالضرورة توقع تنفيذها على الفور بعد Ivy ) ، لأنهم يتعاملون مع الاستخدام اليومي لإطار العمل والتفاعل ، والذي أعتقد أنه لن يجادل أحد ، هو ما يستخدمه معظم الناس (نظرًا لأن ngrx هو أكثر مكتبة إدارة الحالة شيوعًا).

تطبيقي مليء بنصف المخبوزات (ببساطة بسبب القيود التقنية ، بعضها يمكن تنفيذه بشكل صحيح فقط) "polyfills" واختراقات لمعظم هذه المشكلات ، على أمل أن أتمكن يومًا ما من إلقاء نظرة على مواطن أصلي زاوي إستبدال. لكن بطريقة ما لا يبدو أنه قادم.

حسنًا ، دعنا نقول أن مشاركة مدونة تتناول حالة بعض أكبر المشكلات المتعلقة بالتفاعل / تجربة المطورين ستكون موضع تقدير حقيقي.

ماذا عن محاولة كتابة أول إصدار من هذه الميزة بأنفسنا؟ انا
يموت من الملل أثناء كوفيد الشيء الذي يريد أن ينضم إلي؟

فعل العديد من الأشخاص بالفعل ، على سبيل المثال. https://github.com/insidewhy/observable-input

المشكلة في معظم هذه هي أنه للقيام بها بكفاءة ، تحتاج إلى تعديل المترجم أو الأجزاء الداخلية الأخرى من الزاوية.

هذا لا يهم. أعني دعونا نقوم بمساهمة مناسبة للزاوية
النواة. بعد كل شيء ، لدينا شفرة المصدر متاحة. في الواقع ، لا أعتقد أننا سنحتاج حتى إلى لمس المترجم في هذه الحالة.

ganqqwerty حاولت تنفيذه داخل Angular قبل أن أكتب تلك المكتبة. الزاوي معقد للغاية بالرغم من ذلك. لكي نكون منصفين ، فإن الشفرة أكثر قابلية للقراءة والفهم من React ووظائفها المجنونة ذات الخمسمائة سطر ، لكنها "معقدة". وما زلت سأكون سعيدًا لبذل الجهد لتنفيذ هذا التنفيذ إذا اعتقدت أنه يستحق العناء. لكني لا أرى أنه يستحق العناء للأسباب المحددة التي تكررهاfxck أعلاه. لا يستمع فريق Angular إلى المجتمع ، فهم يهتمون باستمرار بالتحسينات والأداء دون الاهتمام بإمكانية استخدام Angular بشكل عام. لا يهمني إطار العمل الذي يعمل بشكل جيد عندما يجبرني على تطبيق Boilerplate للمشكلات البسيطة التي تم عرضها قبل خمس سنوات. لذلك قررت التوقف عن الاهتمام بـ Angular ، وتنفيذ الحد الأدنى من الجهد الذي أحتاجه لدعم المشاريع التي كنت أعمل عليها بالفعل وتجنبها حيثما وأينما كان ذلك ممكنًا لجميع المشاريع المستقبلية.

أعتقد أن هذه ليست مشكلة مع Angular فقط ، ولكن مع العديد من العروض من Google. هذه المشكلة والمشكلات الأخرى التي fxck هي مجرد أمثلة أخرى على المشكلات المستوطنة في Google. إذا ألقيت نظرة على Dart أو GoLang ، فسترى أيضًا أن المطورين يثيرون مشكلات شائعة جدًا معروفة جيدًا وتبقى المشكلات مفتوحة لمدة تزيد عن 5 سنوات.

أوافق على أنه يجب إضافة هذا ، لكن واو ، الكراهية في هذا الموضوع كثيرة بعض الشيء ، أعني أننا نتحدث عن إضافة شيء يحفظ بضعة أسطر من التعليمات البرمجية. يمكنك الآن الحصول على مدخلات يمكن ملاحظتها باستخدام أداة ضبط مزينة بـ

https://github.com/angular/angular/issues/5689#issuecomment -507001686

إذا كان هذا كثيرًا جدًا ، فلدينا بالفعل بعض خيارات الطرف الثالث البسيطة:

https://github.com/Futhark/ngx-observable-input

أنا سعيد بتطوير Angular ، وبالتأكيد لن أتخلى عن إطار العمل الموثوق والمتميز بشكل مذهل بسبب هذه الميزة الصغيرة (وإن كانت مرغوبة)

المشكلة العامة هي في الأساس من منظور كيف يرى الناس ذلك. بالنسبة لشخص ما ، هناك بضعة أسطر من التعليمات البرمجية ويبدو من السهل جدًا تغيير / إضافة أي شيء ، ولكن في الواقع ، هناك الكثير من النطاق الأكبر والعديد من الآثار الجانبية. يجب أخذها جميعًا في الاعتبار وكما هو الحال دائمًا ، فإن سلسلة الموضوعات طويلة وكل شيء له بعض التكلفة والقيمة المضافة والأولوية.

أود أن أشير إلى أنني شخصيًا لا أتوقع بالضرورة حل كل هذه المشكلات على الفور.

لكنني آمل ، الآن ، أن يكون Ivy بعيدًا عن الطريق وخرج في البرية لفترة من الوقت ، سيتم نشر نوع من التحديث الرسمي ، على سبيل المثال ، أهم 25 إصدارًا تم التصويت عليها.

أعني ، لا أجد أنه من الممكن ألا يكون هناك مشروع بهذا الحجم في إدارة المشروع يعتبر من الأولويات ونوع من الخطة لجميع أهم 25 (أو أيًا كان) القضايا التي تم التصويت عليها. معظم هؤلاء لديهم علامة effort . ما عليك سوى إنشاء منشور مدونة ، وإخبار المجتمع بأنك تعرف عن هذه الأشياء وأن لديك نوعًا من الخطة لها.

أنا بالتأكيد لن أتخلى عن Angular أيضًا ، على الرغم من كل أوجه القصور فيه ، ما زلت أحبه أفضل بكثير من جميع البدائل الأخرى. لكنني أعتقد أنه من العدل أن نقول إنه كان يفتقر إلى "إدارة العلاقات المجتمعية" (على github specificaly).

// تعديل

هل تمانع في ملء هذا الاستطلاع؟ بالنظر إلى وضعك الحالي وجميع الأشياء التي تم أخذها في الاعتبار ، فإن أي من هذه المشكلات تؤثر عليك أكثر / من شأنها تحسين تجربة المطور الخاصة بك أكثر https://forms.gle/cprhx239kuqwWd5M8

fxck شكرا لكتابة ذلك. لقد بدأت أتساءل عما إذا كان الجميع قد قبل للتو حقيقة أن فريق Angular سيفعل ما يريد ، عندما يريدون. على الرغم من أن هذا حقهم بالتأكيد ، إلا أنني أعتقد أيضًا أنه من الضروري أن يناديهم الأشخاص عندما يتجاهلون أصوات المطورين باستمرار. أوافق على أنني لا أعتقد أن أي شخص يتوقع حلًا فوريًا للمشكلات ، ولكن تجاهلها لمدة 4-5 سنوات أو مجرد الانتظار حتى يتم قفل المشكلة تلقائيًا يبدو غير مهني حقًا لأي مشروع ، ناهيك عن مشروع تديره Google. لقد اشتروا بعض الوقت من خلال إضافة علامات "Fixed by Ivy" إلى مجموعة من المشكلات المفتوحة ، ثم تابعوا ذلك من خلال عدم القيام بأي شيء.

أنا بالتأكيد لن أتخلى عن Angular أيضًا ، على الرغم من كل أوجه القصور فيه ، ما زلت أحبه أفضل بكثير من جميع البدائل الأخرى. لكنني أعتقد أنه من العدل أن نقول إنه كان يفتقر إلى "إدارة العلاقات المجتمعية" (على github specificaly).

أعتقد أن هذه الجملة تلخص أفكاري تمامًا.

chriszrc لم أفسر أي شيء في هذا الموضوع على أنه "كره". يشبه إلى حد كبير الأشخاص الذين ينفون أخيرًا عن إحباطهم مع تجاهل Angular للقضايا بانتظام لسنوات في كل مرة. لا يتعلق الأمر حتى بهذه القضية على وجه التحديد ، بل يتعلق أكثر بمبدأ الحفاظ على شكل من أشكال التفاعل المجتمعي. هل يعتبر فريق Angular متفوقًا حتى الآن على أي شخص آخر لدرجة أنهم يشعرون أنه يمكنهم تجاهل طلبات المطورين لأنهم يعرفون ما هو الأفضل للجميع؟

chriszrc لا أرى أي كراهية في هذا الموضوع ، مجرد مجموعة من الإحباط المفهومة. أعتقد أن مساواة هذا الطلب وخيبة الأمل المرتبطة بـ "حفظ بضعة أسطر من التعليمات البرمجية" هي مبالغة. ليست هذه المشكلة فقط هي التي تحبط المجتمع ولكن المجموعة الكبيرة من القضايا الشائعة التي أثارها fxck أعلاه والتي تم إهمالها.

مرحباً بالجميع ، أعذرونا للصمت على هذا الموضوع. هناك طلبان متعامدان نتلقاهما منذ فترة:

  1. أفضل دعم RxJS من الدرجة الأولى في الإطار
  2. RxJS أقل في Angular ، مما يجعلها اختيارية

كلا الطلبين على رادارنا ، ولكل منهما إيجابيات وسلبيات. على سبيل المثال ، إذا ذهبنا في الاتجاه الأول ، فسنجعل الوصول إلى إطار العمل أقل سهولة بالنسبة للمهندسين الجدد في واجهة برمجة التطبيقات التعبيرية والغنية بالمعنى لـ RxJS. يشعر الكثير من الأشخاص بالقلق من استخدام RxJS في كل مكان في تطبيقات Angular الخاصة بهم ، مما يجعل قراءة التعليمات البرمجية المصدر صعبة عبر أعضاء الفريق بمستويات خبرة مختلفة.

في الوقت نفسه ، لدينا بالفعل الكثير من واجهات برمجة التطبيقات التفاعلية ، لكن بعض العناصر الأولية التي تقدمها Angular ضرورية تمامًا ، والأشياء لا تعمل بشكل جيد. ومع ذلك ، فمن المنطقي تحسين دعم التفاعل ، ولكن هل ينبغي أن يكون هذا جزءًا من جوهر Angular أو يتم تفويضه إلى مشروع مجتمعي (على سبيل المثال ngrx - الامتداد التفاعلي لـ Angular) الذي نتعاون معه عن كثب؟

هناك العديد من الطرق التي يمكننا من خلالها حل هذه المشكلة ، لكننا بحاجة إلى التفكير في:

  • التوافق مع الإصدارات السابقة - ليس فقط للشفرة المصدرية ولكن أيضًا لمصادر التدريب
  • منحنى التعلم
  • الاتساق مع واجهات برمجة التطبيقات الحالية
  • الاتساق عبر المشاريع
  • الأداء - كل من وقت التشغيل ووقت التحميل الأولي

نحن بصدد تحديد أولويات بعض أهم مشكلات GitHub ، والنظر في التحسينات الأكثر طلبًا والأكثر تأثيرًا التي يمكننا معالجتها. أود أن أقول أن هذه واحدة من أكثر التحديات تحديًا ، لذلك من الصعب الالتزام بموعد.

mgechev شكرا على الرد. إذا كان سيتم تقسيم rxjs و apis التفاعلي إلى امتداد آخر (ليس تصويتي الشخصي) ، فهل سيكون من المنطقي ألا يقترن ذلك بتنفيذ معين لمتجر الدولة / إعادة التشغيل؟ انتقلت بسرعة من ngrx إلى ngxs (التي بدت وكأنها طريقة أقل تشويشًا ، وبطريقة أكثر "زاوية" مع الزينة) ثم أخيرًا إلى Akita ، وهي المفضلة حاليًا والتي كنت أطورها أكثر من غيرها. أو إذا تم تجميعها مع ngrx ، على الأقل اجعل من السهل حقًا إضافة الأجزاء التي نحتاجها ، لذلك نحن لسنا مقيدون باستخدام ngrx أو تضمين تلك التبعيات-

إذا كان سيتم تقسيم rxjs و apis التفاعلي إلى امتداد آخر (ليس تصويتي الشخصي)

أنا لا أقول أن هذا ما سيحدث. في تعليقي ، أشارك فقط قائمة غير كاملة من البدائل حتى أتمكن من إظهار نطاق المشروع والاعتبارات المختلفة التي لدينا.

mgechev حقًا ، شكرًا على الرد.

ومع ذلك ، أتساءل ، إذا كان الجزء التفاعلي من Angular يحصل بطريقة ما على "تخفيض" في مشروع المجتمع ، ألا يعني ذلك أن رد الفعل سيصبح مواطنًا من الدرجة الثانية في Angular؟

mgechev أشعر

فيما يلي متطلباتنا لمثل هذا الانقسام:

  • باستخدام كل من الحاجة الحتمية والتفاعلية للشعور بأنك أصلي ولا يجب أن يشعر أي منهما بالارتباط
  • لا يوجد ارتباط مع حل إدارة حالة محدد لتمكين التفاعل (الإفصاح الكامل ، قمنا بترحيل جميع المشاريع التي يزيد عددها عن 50 مشروعًا لاستخدام akita الآن)
  • يجب إصدار كلا الخيارين في إصدار واحد في نفس الوقت (بدون تأخير / تأخير)
  • لا يمكن أن يكون هناك "مفضل" ، أي شيء تحتاجه الزاوية للعمل في كلا العالمين بينما تشعر أنك أصلي
  • دعم رسمي كامل لكلا الأسلوبين مدعومًا من قبل الفريق الزاوي (بناءً على تجربتنا ، هذا هو أحد متطلبات العميل الصعبة)

بناء على ما سبق:

  • هناك خياران رئيسيان:

    • الأمر الأساسي + الملحق التفاعلي

    • رد الفعل الأساسي + حتمية الملحق

  • التفاف رد الفعل لجعل الأمر يبدو ضروريًا هو أمر مستقيم للأمام ، وليس العكس
  • ومن ثم فإننا نصوت لاستخدام رد الفعل في جوهر وجعل الملحق يحتوي على واجهات برمجة التطبيقات الضرورية
  • نظرًا لعدم التأخير الصفري + عدم وجود متطلبات مفضلة بالإضافة إلى الدعم الرسمي المطلوب ، لا أرى كيف يمكن أن يكون الملحق مشروعًا مجتمعيًا

أفهم أن ما ورد أعلاه هو نظرتنا إلى العالم وهناك الكثير من الآخرين. سبب كتابتي لهذا هو:

  • إذا وصلت إلى الاستخراج التفاعلي في مشروع مجتمعي ، فسيتعين علينا ترحيل أكثر من 50 حلاً إلى إطار عمل آخر (مرة أخرى ، سيكون هذا مدفوعًا بالعميل ، وليس اختيارنا)
  • لذلك أود أن أطلعنا (المجتمع) في أسرع وقت ممكن على المكان الذي تهبط فيه على هذا حتى يكون لدينا الوقت لإعادة تدريب مطورينا على إطار عمل آخر وترحيل تلك المشاريع

أضف الميزة من فضلك

mgechev أنا لا أفهم مخاوفك. يتعلق هذا الاقتراح بدمج العالمين مع واجهة موحدة ومباشرة للمطورين المبتدئين. لا يتعلق الأمر باختيار أحدهما أو الآخر بل يتعلق بتمكين المجموعة. على سبيل المثال ، قرر المطور x إنشاء مكون تفاعلي رائع. ويقرر المطور y استخدامه في مشروعه غير التفاعلي. ولم لا؟ لماذا يحتاج إلى الاعتماد على أي غراء ngrx؟
الفرق بين العالمين هو ما إذا كنت تقوم بتخزين / إدارة الحالة في المكون الذكي النهائي الخاص بك مقابل متجر الدولة المركزي وهذا ما يجب أن تكون عليه ngrx ، لكن بالنسبة للمكونات أشعر أن الإطار نفسه يجب أن يكون العامل التمكين.

هناك طلبان متعامدان نتلقاهما منذ فترة:

  1. أفضل دعم RxJS من الدرجة الأولى في الإطار
  2. RxJS أقل في Angular ، مما يجعلها اختيارية

سأكون بخير في كلتا الحالتين ، لكن هذا أحيانًا يعطي إحساسًا مفككًا لـ Angular ، وهو آخر شيء يمكن أن تستثنيه من إطار العمل المتضمن البطاريات.

أنا شخصياً أشعر بالفضول لمعرفة كيف سيكون لديك حتى إصدارات بخلاف RxJS لجميع الحزم Angular (HTTP ، Router ، Forms). أظن أنه لا توجد إصدارات جيدة بخلاف RxJS من هذه ، ولهذا السبب لديهم RxJS في المقام الأول.

هذا يعني ... ما لم أفقد شيئًا ، (2) غير ممكن.


ملاحظة: لن أصف هذه الطلبات بأنها "متعامدة". أكثر مثل "العكس".

RxJS أقل في Angular ، مما يجعلها اختيارية

بدافع الفضول mgechev ، هل هناك أي مشكلات في Github لذلك؟ (لم أر أي شيء.) أم أن هذا الأمر يتعلق بموظفي Google؟

pauldraper لقد رأيت مشكلة واحدة على الأقل على github حيث يشتكي شخص ما من مدى تعقيد rxjs ويريد أن يكون اختياريًا تمامًا. أنا شخصياً أحب rxjs ، لكنني عملت مع فريقين الآن حيث جلبت الخوف والبغضاء لكل من المطورين الصغار والكبار. أيضًا ، المتعامد هو المصطلح الأفضل من العكس ، لأنه من الممكن تنفيذ كلا الطلبين في نفس الوقت (نظرًا لأن كل حل يمكن أن يعمل دون أن ينتقص أحدهما من الآخر من خلال توفير خيارات واجهة برمجة تطبيقات متعددة لاستهلاك الأشياء بشكل تفاعلي وحتمي).

مقابل كل تعليق يشتكي من rxjs على جيثب ، هناك على الأرجح الآلاف من المطورين الذين يستخدمونه ويستمتعون به دون مشكلة.

image

image

فيما يلي نتائج هذا النموذج الذي نشرته أعلاه (استجاب ما يقرب من 200 شخص) ، حيث كنت أناقشهم حول الخلاف الزاوي.

ليس من المستغرب أن الأشكال هي أكبر ألم في المؤخرة ، ولكن من الواضح أن brandonroberts و MikeRyanDev قد يطبخان شيئًا ما أخيرًا.

مقابل كل تعليق يشتكي من rxjs على جيثب ، هناك على الأرجح الآلاف من المطورين الذين يستخدمونه ويستمتعون به دون مشكلة.

على الرغم من أنني أحب rxjs ، فأنا لست بهذا التفاؤل. لقد عملت مع الكثير من المطورين الذين أرهقهم التفكير في الاضطرار إلى تخصيص وقت لتعلم شيء ما مع منحنى تعليمي حاد هو كابوس. والكثير ممن يهتمون بكسب المال أكثر من البرمجة: D أو المطورين المبتدئين العدوانيين الذين يعتقدون أن أي شيء لا يمكنهم تعلمه في غضون يوم واحد يجب أن يكون هراء.

لقد عملت مع الكثير من المطورين الذين أرهقهم التفكير في الاضطرار إلى تخصيص وقت لتعلم شيء ما مع منحنى تعليمي حاد هو كابوس. والكثير ممن يهتمون بكسب المال أكثر من البرمجة

هؤلاء هم devs Angular الذي يحاول تلبية احتياجاتهم ، محترقين وبدون الرغبة في التعلم؟ :) ومن يهتم حتى في هذا الوقت على أي حال. Angular موجودة منذ فترة ، ولن تذهب إلى أي مكان ولن تفقد أي جر إذا أضفت دورة حياة يمكن ملاحظتها ، ومدخلات يمكن ملاحظتها ، وأحداث يمكن ملاحظتها. ما عليك سوى إضافة هذه الأشياء الصغيرة الثلاثة وسيسعد الناس لفترة من الوقت ، هذا كل شيء (واتبع ذلك باستخدام https://indepth.dev/component-features-with-angular-ivy/ لإكمال الحزمة الأساسية).

angular_rxjs

هذا واحد يقول كل شيء. يجب أن يظل IMHO Angular ثابتًا ويستخدم المزيد من RxJS: مع عدم وجود RxJS على الإطلاق ، لن يكون Angular.

هؤلاء هم Devs Angular's الذي يحاول تلبية احتياجاتهم بعد ذلك؟ :)

نعم ، سيكون من الغريب تلبية احتياجات المطورين الذين يرغبون في كتابة التعليمات البرمجية باستخدام rxjs فقط. على الرغم من أنني أفضل استخدام rxjs ، إلا أنني أريد أن يلبي Angular كلا المجموعتين من المطورين. لماذا يجب على Angular أن يلبي احتياجاتنا فقط وليس أولئك الذين يفكرون بشكل مختلف؟ خاصة عندما أعتقد أننا أقلية وليس أغلبية.

مرة أخرى ، فإن الذهاب إلى "رد الفعل الكامل" ، كما هو الحال في إضافة دورات حياة يمكن ملاحظتها ، ومدخلات ، وأحداث لن تؤثر بأي شكل من الأشكال على من تتحدث عنهم ، ولكنها ستجعل المجموعة الأخرى سعيدة جدًا.

وميزات المكونات مفيدة سواء كنت تحب البرمجة التفاعلية أم لا.

fxck لم اختلف مع ذلك لثانية واحدة. كنت أرد للتو على تعليقك السابق للإشارة إلى أن هناك العديد من الأشخاص الذين لا يرغبون في استخدام rxjs والعديد منهم فتحوا مشكلات github للشكوى من ذلك.

على الرغم من الكيفية التي يقرر بها الزاوي تطوير النواة - بشكل تفاعلي أم لا ، في العالم المثالي سيكون هناك حزمة معاكسة مبنية في الأعلى لتلبية الاحتياجات المعاكسة (على سبيل المثال ، @angular/reactive أو @angular/imperative - بأسماء أفضل نأمل).

أي من هذين الذهابين إلى المجتمع هو بالنسبة لي تخفيض التصنيف بالنسبة لبعض الناس وبالنسبة لي الزاوي وجود نظرة مستقبلية لكونه إطار عمل تفاعلي رائع كان سببًا للذهاب معه في المقام الأول.


في ملاحظة جانبية ، أعتقد أنه سيكون من الأسهل الحفاظ على رد الفعل الزاوي والحصول على امتدادات حتمية ، لأن هذا أسهل في الجسر ، بدلاً من سد الحاجة إلى رد الفعل - التحدث عن بساطة كل من الحزمة الأساسية والامتداد.

إخلاء المسئولية: النقطة الأخيرة التي قمت بصياغتها بناءً على الافتراضات - لن أتفاجأ إذا كان من الأسهل بكثير كتابة الأمر الأساسي - سيكون رد الفعل التمديد أكثر تعقيدًا.

بدافع الفضول mgechev ، هل هناك أي مشكلات في Github لذلك؟ (لم أر أي شيء.) أم أن هذا الأمر يتعلق بموظفي Google؟

ليس شيئًا داخليًا في Google. ستندهش (مثلما كنت ، عندما انضممت إلى الفريق) ، ما هو حجم التقاطع بين المتطلبات الخارجية والداخلية. يكمن الاختلاف الرئيسي في نظام الإنشاء وإدارة التبعية ، بصرف النظر عن أن موظفي Google لديهم إلى حد كبير نفس المتطلبات مثل غير موظفي Google.

نحن على اتصال بآلاف المطورين - الكثير من الشركات الخارجية والفرق الداخلية والمساهمين الفرديين. في كلتا الحالتين ، هناك أشخاص يرغبون في المشاركة بشكل كامل مع RxJS وآخرين لا يعتقدون أنه الخيار الصحيح لهم. كلا المعسكرين لديهم حجج ممتازة.

هذا ليس قرارًا نرغب في التسرع فيه ، لا سيما بالنظر إلى وجود حلول بديلة / حلول مجتمعية راسخة. يساعدنا العمل المنجز في المجتمع على جمع نقاط بيانات إضافية وإنشاء حل مثالي لمجموعة المتغيرات الحالية.

أعتقد أن وجود نهج واحد موحد تفاعلي أو إلزامي (كونه اختيارًا لكل مشروع) عند تطوير تطبيق زاوي سيكون مفيدًا للغاية. القدرة على المزج والمطابقة لا تساعد في تطوير تجربة وإنشاء رمز غير جاف (على سبيل المثال. المدخلات غير التفاعلية).

لا شيء يحدث بمعزل عن الآخرين ، لذلك يمكنني أن أفهم تمامًا بيئات الشركات التي تواجه صعوبة في إعادة تدريب كميات كبيرة من المطورين على البرمجة التفاعلية. لذا فإن إسقاط الأمر الحتمي من شأنه أن يتحرك بشكل زاوي من النقطة المثالية للشركة ، والذي يتيح لك الواقعية لن يحدث لأنه يشكل قاعدة مستخدم رئيسية كبيرة لإطار مثل الزاوي.

ومع ذلك ، فإن ما لا أراه واقعيًا هو بناء واجهة تفاعلية فوق واجهة ضرورية. الاتجاه الآخر مستقيم إلى حد كبير حيث يمكنك دائمًا كتابة ناتج متغير يمكن ملاحظته في متغير يمكن استخدامه بعد ذلك بشكل إلزامي. في الواقع هذا ما تفعله الزاوية بالفعل في العديد من الأماكن تحت الغطاء.

ومن ثم فإنني أصوت لجعل الزاوي متفاعلًا تمامًا في جوهره ثم أنشئ "أغلفة" ضرورية في الأعلى.

من المحتمل جدًا أن تكون المشكلة الرئيسية في هذا النهج هي خطوات ترحيل أكبر للمستخدمين الضروريين. وهو عبارة عن نونو في بيئات الشركات والذي قد يكون بالضبط ما يحاول الفريق الزاوي منعه ، ومن هنا جاء اقتراح القيام بالأمر الحتمي في جوهره.

mgechev نظرًا لأن هذا قد تم رفعه عدة مرات ، سيكون من المثير للاهتمام سماع أفكارك حول رد الفعل الأساسي / التمديد الضروري وما إذا كان لديه أي ساق للوقوف عليها؟

في كلتا الحالتين ، هناك أشخاص يرغبون في المشاركة بشكل كامل مع RxJS وآخرين لا يعتقدون أنه الخيار الصحيح لهم. كلا المعسكرين لديهم حجج ممتازة.

عظيم ، من الجيد أن تعرف. حدد الانطلاق الكامل مع RxJS؟ كيف يمكن إضافة دورة حياة يمكن ملاحظتها ، ومدخلات يمكن ملاحظتها وأحداث يمكن ملاحظتها؟ ولا ، ليس لدى أي من هؤلاء حقًا "حلول راسخة / حل مجتمعي".

fxck ليس لدى أي من هؤلاء حقًا "حلول راسخة / حل مجتمعي".

هذا صحيح. لقد كتبت أحد هذه الحلول وهو يعمل فقط بسبب اختراق واحد كبير يعتمد على تدقيق النوع السيئ في القوالب. لقد قمت بفحص عدد قليل من الحلول الأخرى المنشورة في هذا الموضوع أيضًا وكل واحد منهم لديه واحدة على الأقل من المشاكل التالية:

  • تسريبات الاشتراك
  • المتطلبات المعيارية على المستخدم
  • الاختراقات سيئة ، إن لم تكن أسوأ ، من تلك التي استخدمتها في مكتبتي.

بقدر ما أشعر بالقلق ، من المستحيل القيام بذلك بشكل جيد.

الأحداث التي يمكن ملاحظتها أسوأ من ذلك ، لا توجد العديد من الحلول المجتمعية على الإطلاق ، فهي تتطلب عادةً خطوة بناء إضافية (والتي في بعض الحالات تكسر SSR في إعدادات monorepo) والاختراقات فوق ذلك (إذا كنت تستخدم امتداد الفصل على سبيل المثال احصل على أحداث يمكن ملاحظتها في دورة الحياة ، لأن الزاوي لا يدعم ذلك أصلاً) https://github.com/typebytes/ngx-template-streams/issues/8

يمكن القول إن أحداث دورة الحياة هي "الأسهل" ، ولكن لا يزال يتعين عليك الاعتماد على ملحق فئة أو أدوات تزيين مخصصة ، ولا يعتبر أي منها مثاليًا.

fxck على حد

يمكن القول إن أحداث دورة الحياة هي "الأسهل" ، ولكن لا يزال يتعين عليك الاعتماد على ملحق فئة أو أدوات تزيين مخصصة ، ولا يعتبر أي منها مثاليًا.

لقد حاولت تنفيذ أحداث دورة الحياة (لجعلها تفاعلية) باستخدام أدوات تزيين مخصصة أيضًا وهذا أمر مؤلم. ~ بدون ملحق الفصل ، لا أعرف ما إذا كان ذلك ممكنًا بدون 100 قرصنة ~. إن إمكانية المستخدم لتوسيع الزاوية ضعيفة للغاية حتى الآن وتعتمد على الاختراقات أو الكثير من النماذج المعيارية للقيام بذلك.

@ tonivj5 إذا كانت ميزة المكون ستكون واجهة برمجة تطبيقات عامة ، فهل ترى أن هذه طريقة محتملة لتنفيذ دورات الحياة بدون وراثة؟

ntziolis hah مضحك يجب أن تذكر الميزات ، فأنا أعمل بالفعل على جزء دورة الحياة من النموذج الفرعي ngx والميزات هي بالضبط شيء أعتقد أنه سيساعد. في غضون ذلك ، من الممكن جدًا ترقيع مصنع المكونات باللبلاب. أرى أن هذا مفيد جدًا خارج النموذج الفرعي ngx ، لذلك أعتقد أنني سأقسم هذا المنطق إلى lib منفصل

ntziolis في هذه المرحلة ، لست متأكدًا مما إذا كنا سنرى وعود Ivy يتم تسليمها بالفعل.

هل راجعت التأثير الزاوي؟ (وليس ngrx / التأثيرات) https://dev.to/stupidawesome/reactive-adventures-in-angular-introducing-angular-effects-1epf باستخدام هذه الأداة يمكنك كتابة تطبيقات تفاعلية بالكامل.
تم تضمين حالة ثنائية الاتجاه يمكن ملاحظتها بين مكونات الوالدين والأطفال
https://dev.to/stupidawesome/exploring-the-angular-effects-api-2gol
سيقدم الإصدار 9.1.0 نموذج تكوين / خطافات يعتمد على واجهة برمجة تطبيقات التكوين الخاصة بـ Vue 3.
أعتقد أنها الخطوة التالية حقًا للعمل الزاوي مع التفاعل.

تضمين التغريدة

هذا ليس قرارًا نرغب في التسرع فيه ، لا سيما بالنظر إلى وجود حلول / حلول مجتمعية راسخة

مجرد فضول ، من نحن وكم عدد موظفي Google الذين يساهمون بنشاط في عملية صنع القرار في Angular؟

أنت تشير إلى أن هذا ليس قرارًا يجب التسرع فيه ، لكني أتساءل ما هو تعريفك لـ "عدم التسرع"؟ هل هذه واحدة من هؤلاء الذين يصفعون علامة "Fixed by Ivy" عليها ويتجاهلونها حتى يبدأ المزيد من المطورين في إصدار الضجيج مرة أخرى اكتب المواقف؟ هل هناك نسخة مستهدفة في الاعتبار لأي عمل تفاعلي أم أن هناك إصدارات أخرى من المترجم يجب إصدارها أولاً؟

هل حقيقة أن هناك عادة 2500 قضية مفتوحة في أي وقت قد ظهرت في المناقشات الداخلية؟

ntziolis ، كما قال zakhenry ، أعتقد أن features سيساعد

ntziolis لقد قمت ولدي POC عامل (بدون امتداد للفئة ولا ينفذ واجهات دورة الحياة). يعتمد على واجهة برمجة تطبيقات خاصة (: تعجب :)

@ tonivj5 ههه لم تسنح لي الفرصة لقراءة أوشكت على إطلاق الحل الخاص بي أيضًا :) https://github.com/cloudnc/ngx-observable-lifecycle

الفكرة مع lib الذي أعمل عليه هي الحصول على قاعدة مشتركة يمكن للليبس الآخرين الارتباط بها لإنشاء وظائف مدركة لدورة الحياة الخاصة بهم. يجب أن يكون قادرًا على العمل بحيث إذا كانت هناك وظائف متعددة تريد الوصول إلى نفس الخطاف ، فلا يوجد سوى خطاف واحد مزين على عنصر تعريف المكون.

لقد نجحت في كل شيء ، فقط أحتاج إلى فرز اختبارات الوحدة والقسم.

هل حقيقة أن هناك عادة 2500 قضية مفتوحة في أي وقت قد ظهرت في المناقشات الداخلية؟

لول ، لم يكن هناك 2500 إصدار مفتوح منذ منتصف عام 2019.

$ github_issue_stats history -i2m -n20 -sangular/angular

+-------------------------+--------------------+
|         period          |       issues       |
+-------------------------+--------------------+
| This month (2020-05)    | 2855 (+137, -112)  |
| Last month (2020-03)    | 2830 (+495, -550)  |
| 2 months ago (2020-01)  | 2885 (+601, -575)  |
| 3 months ago (2019-11)  | 2859 (+437, -352)  |
| 4 months ago (2019-09)  | 2774 (+411, -305)  |
| 5 months ago (2019-07)  | 2668 (+441, -369)  |
| 6 months ago (2019-05)  | 2596 (+488, -349)  |
| 7 months ago (2019-03)  | 2457 (+425, -373)  |
| 8 months ago (2019-01)  | 2405 (+428, -330)  |
| 9 months ago (2018-11)  | 2307 (+425, -391)  |
| 10 months ago (2018-09) | 2273 (+515, -466)  |
| 11 months ago (2018-07) | 2224 (+641, -541)  |
| 12 months ago (2018-05) | 2124 (+690, -624)  |
| 13 months ago (2018-03) | 2058 (+605, -444)  |
| 14 months ago (2018-01) | 1897 (+773, -679)  |
| 15 months ago (2017-11) | 1803 (+815, -979)  |
| 16 months ago (2017-09) | 1967 (+671, -431)  |
| 17 months ago (2017-07) | 1727 (+664, -518)  |
| 18 months ago (2017-05) | 1581 (+854, -548)  |
| 19 months ago (2017-03) | 1275 (+987, -796)  |
| 20 months ago (2017-01) | 1084 (+671, -505)  |
+-------------------------+--------------------+

حسب ذوقي ، أفضل المشاريع مفتوحة المصدر التي تبقي القضايا مفتوحة للمناقشة حتى يكون هناك مناقشة / إجماع مجتمعي واضح بدلاً من المشاريع التي تغلق كل قضية مفتوحة دون مناقشة. إنها أيضًا خطوة بالنسبة للمشرفين لشرح مخاوفهم مع مرور الوقت للمجتمع قبل أن يغلقوا أي احتمال لقبول الاقتراح.

agalazis تم فتح هذه المشكلة لمدة 4 سنوات ونصف وتم تجاهلها إلى حد كبير في آخر 3 سنوات.

agalazis تم فتح هذه المشكلة لمدة 4 سنوات ونصف وتم تجاهلها إلى حد كبير في آخر 3 سنوات.

كان هناك أحد أعضاء فريق Angular يشرح سبب استمرار فتحه منذ 5 أيام فقط ، لذا فأنت ببساطة لست على حق.

@ etay2000 بعض القرارات تكون صعبة في بعض الأحيان لأنها تؤثر على تطور المشروع بأكمله وهذا مقبول يمكن للمطورين أن يدركوا أنهم لا يستطيعون الاعتماد على الميزة في المستقبل القريب مع مرور الوقت ، ولكن إذا كان هناك احتمال لماذا قتلها قبل الأوان؟ أعتقد أن أسهل شيء هو رفض الاقتراح وإغلاق القضية ولكن ذلك لم يحدث لسبب ما.

تضمين التغريدة

كان هناك أحد أعضاء فريق Angular يشرح سبب استمرار فتحه منذ 5 أيام فقط ، لذا فأنت ببساطة لست على حق.

أنت حقا تحب تلك الرموز التعبيرية لأسفل ، هاه؟ هل كان هذا تفسيرًا حقًا؟ بعد أكثر من 4 سنوات قال إنهم لا يريدون التسرع في اتخاذ القرار.

تضمين التغريدة
أوافق على أن بعض القرارات صعبة ، ولكن ما الذي يجب اعتباره إطارًا زمنيًا مقبولاً لتأجيل اتخاذ تلك القرارات الصعبة؟ لا تتضمن جميع القضايا المفتوحة البالغ عددها 2855 هذه القرارات الصعبة ، ومع ذلك فإن الكثير منها كان موجودًا أيضًا لبعض الوقت أيضًا.

@ etay2000 تقبلها أو لا المشرفين . على سبيل المثال ، يحتوي مشروع تنضيد النص على ما يقرب من ضعف عدد المشكلات المفتوحة ، واستغرق اقتراح آخر قمت به هناك وقتًا طويلاً أيضًا. لا أمانع منذ المناقشة التي جلبت هناك العديد من البدائل التي لم تكن رائعة مثل امتلاك الميزة ولكنها تمكنت من رؤية الكثير من وجهات النظر الأخرى

agalazis أنت على حق ، أعتقد أنني (بشكل غير صحيح) توقعت من مشروع مفتوح المصدر

beeman أدخل

@ etay2000 يجب أن تتذكر دائمًا أن كل قرار مهم من هذا القبيل يؤثر على مئات الآلاف من الأشياء والمشروعات والأشخاص. والأهم من ذلك ، القرار غير المثالي وإدخال واجهات برمجة التطبيقات العامة ، التي من شأنها أن تؤدي إلى بعض التغييرات العاجلة في وقت قصير بعد ذلك ، هو مجرد كابوس. يمكنك أن ترى تقريبًا في كل علاقات عامة ، وكيف تتم مراجعة كل خطوة ، وإذا لم تكن مثالية ، فهي ببساطة تنتظر ، أو أسابيع ، أو شهور ، أو حتى سنوات.

agalazis أنت على حق ، أعتقد أنني (بشكل غير صحيح) توقعت من مشروع مفتوح المصدر

لا أعرف ، انظر إلى Go and dart أيضًا. تشتهر Google في الواقع بتجاهل طلبات المجتمع التي تحظى بشعبية كبيرة لمدة نصف عقد: D بشكل عام نهجها تجاه اللغات / أطر العمل / إلخ. محافظ جدا . يمكنك رؤية لغات وأفكار جديدة تظهر ثورة في المناطق ولا يزال Google لا يستخدمها لسنوات ، على سبيل المثال ، ضرب الأمان الفارغ Kotlin و TypeScript و Scala قبل وقت طويل من Dart. أعتقد أن هناك مزايا وعيوب لهذا النوع من النهج ، لكن بالنسبة لي على الأقل أميل إلى تجنب الأشياء التي طورتها Google حيثما أمكن ذلك لأنها لا تتناسب حقًا مع روحي.

(آسف لهذا ، الجميع ، لكن علي أن أفعل ذلك.)

beeman أدخل

@ etay2000 لا أعرف كيف يساعد هذا النوع من التعليقات على الإطلاق ، إن لم يكن انتهاكًا للسلوك هنا. أنا متأكد من أن الجميع يعرف كيف يضعون الإبهام لأسفل ، فما الهدف من السخرية؟

فقط للتذكير ، لا أحد مجبر على استخدام Angular ، يمكنك محاولة العثور على إطار عمل آخر حيث يرضيك الناس أكثر.

brunojcm أعتقد أن الحفلة انتهت الآن بعد أن أصبحت شرطة التعليق هنا. كانت النقطة هي أنه تجاهل جميع تعليقاتي الأخرى ، لكنني لم أدرك أن السخرية كانت انتهاكًا للسلوك.

فقط للتذكير ، لا أحد مجبر على استخدام Angular ، يمكنك محاولة العثور على إطار عمل آخر حيث يرضيك الناس أكثر.

الطريقة التي أريد بها الرد على ذلك ستنتهك بالتأكيد مدونة السلوك هنا.

لقد انتهيت ، يمكن للجميع العودة إلى برامجهم المجدولة بانتظام. سوف أتحقق مرة أخرى بعد 4-5 سنوات أخرى لأرى كيف تحولت الأمور.

@ tonivj5zakhenry العظيم أن نسمع أن هذا قد يكون وسيلة.

mgechev أفهم أن هذا ليس حتى مناقشة أولية ، لكني أحب أن أسمع أفكارك حول:

  • رد الفعل الأساسي + التمديد غير التفاعلي مقابل العكس.
  • والأكثر تحديدًا لهذه المشكلة ، هل هناك أي فرصة واقعية لكشف ميزة API بأي شكل من الأشكال.

    • حتى لو كان ذلك فقط مع تحذير من كسر التغييرات في المستقبل طالما أن الوظيفة العامة لا تزال متاحة.

    • كما فعلzakhenry لأحداث دورة الحياة ، أرى عددًا واحدًا أو عددًا محدودًا جدًا من المشاريع التي تبني واجهات برمجة التطبيقات في الأعلى والتي يمكن أن يستخدمها الآخرون بدلاً من الوصول المباشر إلى واجهات برمجة التطبيقات هذه

    • يمكنك بعد ذلك العمل مع فريق / فرق التجميع هذه لإعلامهم بالتغييرات القادمة في وقت مبكر (تشبه إلى حد كبير اقتراحك بشأن الامتدادات التفاعلية)

أعتقد أن بإمكانكم يا رفاق تطبيق الوحدة التفاعلية الخاصة بـ Vue 3.0 مباشرة (المرجع أو رد الفعل) وحل هذه المشكلة.

AnonymousArthur إذا كنت تتحدث عن الحزمة @vue/reactivity فهذا لا علاقة له تمامًا بما نناقشه هنا لأنه يوفر تفاعلًا مع الخصائص ولا علاقة له بالتدفقات المتكررة (وهو ما هو RxJs).

gund نعم ، أوافق. ومع ذلك ، تستغرق هذه المحادثة وقتًا طويلاً (4.5 سنوات) ولم تنته بعد ، لذلك ظهرت فكرة (قد لا تكون) بسرعة كبيرة بالنسبة لمن لا يريدون كتابة اشتراك / إلغاء اشتراك أو معالج ngOnChange. توفر RxJS ميزة تفاعلية وهذه المحادثة (لم تقرأها كلها) تتحدث عن تغليف قيمة الإدخال مع الملاحظة كسكر نحوي لجعلها قابلة للمشاهدة وأعتقد أنها فكرة رائعة.

أعتقد أن هذه الفكرة مفيدة حقًا وأن النموذج الأولي لـ robwormald في البداية يبدو رائعًا ، لكنني أعتقد أنه قلل من قيمة الفوائد المحتملة ومدى ضآلة التأثير الذي يجب أن يكون.

اسمحوا لي أن أقترح تعديلًا طفيفًا على هذا الحل لإصلاح بعض أوجه القصور ، ولكن في الأساس نفس النهج:

يحدد Angular مصمم الديكور @OInput() والنوع EventReceiver<T> الذي يمتد Observable<T> ولكنه يضيف أيضًا .value getter (مثل BehaviorSubject<T> ).

على جانب المكون الأصلي ، كما في مثالrobwormald ، لا شيء يتغير. إذا كنت تريد تمرير قيمة يمكن ملاحظتها هناك ، فلا تزال بحاجة إلى | async . أو يمكنك تمريرها إلى نوع غير ملحوظ ، فلا بأس (كما هو الحال دائمًا) أيضًا.

على جانب المكون الفرعي ، هذا ما أقترحه يبدو (انحراف طفيف عن هذا الاقتراح):

@Component({ selector: "child" })
class Child {
  // Notice, this parallels the patterns of `@Output()`.
  @OInput() foo = new EventReceiver<MyType>();

  constructor() {
    // The reactive way to listen to input changes in the class.
    this.foo.subscribe((v) => {
      console.log('foo changed', v);
    });
    // Or you can bind to `foo | async` in the template.
  }

  // But this would also support less reactive patterns in parallel,
  // both for ease of migration and for cases where developers don't
  // want to migrate fully. 
  ngOnChanges(changes: SimpleChanges) {
    if (changes['foo']) {
      console.log('foo changed', changes['foo'].currentValue); // Unchanged
      console.log('foo changed', this.foo.value);  // Previously this would have been just `this.foo`
    }
  }
}

الآن إليكم فوائد هذا النهج ، والتي أشعر أنها كانت أقل من البيع قليلاً:

  • يتيح ذلك تصميمات تفاعلية بشكل فعال في كل من المكونات الأصلية والفرعية ، إذا رغبت في ذلك.
  • في المكونات الأصلية ، يحافظ على أنماط تصميم الإدخال الحالية لـ Angular ، بحيث لا يتم إجبار أي مكون على ذلك أو يجب تصميمه حوله.
  • سياق الوالدين والفرع مستقلان تمامًا ، ولا يحتاج الوالد إلى معرفة ما إذا كان الطفل يستخدم Input أو OInput ، مما يزيل مخاطر الأخطاء المشتركة بين المكونات من هذا التغيير.
  • من السهل نسبيًا ترحيل مكون فرعي واحد جزئيًا ، إذا رغبت في ذلك ، لأن Angular تحافظ على كل هذه العناصر متصلة بأحداث دورة الحياة الحالية كما كان من قبل.
  • نظرًا لأن Angular تنفذ هذه الميزة ، يمكن لجميع EventReceiver s أن تتضمن أنبوبًا داخليًا عبر takeUntil(ngOnDestroyEvent) ، لذلك لن تحتاج معظم الحالات إلى تذكر إلغاء الاشتراك عند تدمير المكون الخاص بها ، لأن هذه العناصر المرصودة ستكتمل تلقائيًا . (يا قلل تسرب الذاكرة!)
  • في هذا المكون الفرعي ، يبدو هذا ويعمل بشكل مشابه جدًا لنمط @Output() اليوم ، لذلك يعطي بعض التوازي اللطيف والقدرة المحتملة على ربطهما بشكل جيد.

    • ملاحظة جانبية: كمتابعة ، أعتقد أنه سيكون من الرائع اقتراح @InputOutput() يستخدم ReplaySubject<T>(1) لربط السلوكيات لربط ثنائي الاتجاه بشكل أكثر سلاسة وثباتًا. لكن هذا له تحدياته وحججه الخاصة ، لذلك أنا لا أقترح ذلك هنا.

  • لا توجد أنواع جديدة من النماذج المعيارية لإنجاز هذا العمل ، هذا بسيط مثل @Output() .
  • سوف Angular switch() بسلاسة أكثر من التغييرات إلى Observable التي يتم إدخالها من قبل الوالدين ، لذا فإن الأنماط التفاعلية الأضعف مثل تلك التي لا تلتصق بنفس المثيل المرصود لا تحتاج إلى أن تكون ذات غلاف خاص ( switch() ed) في المكونات الفرعية.

ملاحظة جانبية حول الاسم OInput الذي اخترته: من الواضح أن هذا مفتوح للنقاش. ومع ذلك ، أنا شخصياً أحب هذا الاسم لأنه اختصار لـ "المدخلات المرصودة" ولأنه يشبه نوعًا ما "الإخراج" وهو ما يعكسه هذا الاسم.

عزيزي فريق Angular. يرجى إعطائنا شيئًا نتطلع إليه في عام 2020 :-)

أيضًا حل jcomputer هو بالضبط ما @ViewChild { read } . على سبيل المثال:

@Input({ observable: true }) 
@Input({ asObservable: true }) 
@Input({ asSubject: true })

الكثير لامتلاك شيء نتطلع إليه في عام 2020.: D ما لم يكن هذا بالطبع (وغيره من المشكلات المذكورة أعلاه) يعتبر خطأً وليس ميزة جديدة. :)

https://twitter.com/ThomasBurleson/status/1283902827467886592
image

fxck قد يكون لدي رأي غير شعبي هنا ولكن بصراحة إذا كان عام 2020 هو العام الذي قرر فيه فريق Angular سحق الكثير من الأخطاء في النماذج وأجهزة التوجيه وما إلى ذلك ، فلن أكون غاضبًا على الإطلاق مع 0 ميزات : تجاهل :.

image

بعد قولي هذا ، ربما يتعلق الأمر بالأحداث الأخيرة وأعتقد أن هناك أشياء معقدة تحدث في الوقت الحالي في فريق Angular. آمل أن يتمكنوا من الحفاظ على الأشخاص العظماء الذين عملوا بنشاط على بناء Angular حتى الآن: القلب:. لكن هذه قصة أخرى.

آسف للموضوع خارج. يطير بعيدا

@ maxime1992 سيكون جيدًا بالنسبة لي أيضًا.

قد يكون لدي رأي لا يحظى بشعبية هنا ولكن بصراحة إذا كان عام 2020 هو العام الذي قرر فيه فريق Angular سحق الكثير من الأخطاء على النماذج وجهاز التوجيه وما إلى ذلك ، فلن أكون غاضبًا على الإطلاق مع 0 ميزات

ولكن ما يجعلني أشعر بالتوتر هو حقيقة أن هناك عمليات موارد بشرية غير صحية طويلة المدى داخل فريق Angular والتي تؤثر علينا ، بدوننا. خاصة من وجهة نظر الاستثمار الضخم في هذا المجال.

من POV الخاص بي ، يقومون بإصلاح المشكلات بشكل أساسي عن طريق إغلاقها عبر BOT - المغادرة دون رد والإغلاق بواسطة الروبوت ..: - /

@ montella1507 لا ، هذا ليس صحيحًا تمامًا. يقوم الروبوت بتأمين المشكلات التي تم إغلاقها بالفعل فقط. ومن الصحيح بالفعل أن أعضاء فريق Angular لديهم الكثير من الجهد في كثير من الحالات عندما يحاولون شرح ما هو ضروري لوصفه وإعادة إنتاجه عند إدخال مشكلات جديدة. إنها عملية تستغرق وقتًا طويلاً وتتطلب الكثير من الصبر.

بالنسبة لأولئك الذين يلومون فريق Angular ويشكون من عدم الحصول على الميزات والتغييرات بسرعة:
أنا أفهم ألمك. أود أيضًا أن أرى هذه الميزة في Angular ، كما أنني سأغير الكثير من الأشياء التي لا أحبها شخصيًا.

ولكن ربما لا يُقصد من Angular أن يكون إطارًا يحتوي على كل الألعاب الجديدة اللامعة والحصول على الكثير من الميزات في كل إصدار. وهذا جيد بالنسبة لي. يجب أن تكون هناك أطر عمل تهدف إلى مزيد من مستوى المؤسسة وتوفر الاستقرار والموثوقية. و Angular يفعل ذلك على ما يرام ، على الأقل من تجربتي.

أنا أحب Vue أكثر. أنا أستخدمه لمشاريعي الشخصية. ولكن يمكن أن تبدأ بسرعة في الشعور بأن مشاريعي أصبحت قديمة وأشعر بالحاجة إلى الترقية إلى نمط مكون جديد. أيضًا ، عندما أقوم بإجراء ترقيات ، تنكسر الأشياء دائمًا بأغرب طريقة. يبدو أيضًا أن النظام البيئي يواجه صعوبة في الحفاظ على التوافق.

الزاوي على النقيض من ذلك هو ناضج ومستقر. لا يتغير كثيرًا ، ولكن هذا يعني أيضًا أن لديك جهدًا أقل في إعادة بناء الكود الخاص بك بينما تحافظ على تبعياتك محدثة ، وهذا أمر ذو قيمة للمنتجات التجارية. تظل معرفتك أيضًا ذات صلة لفترة أطول ، وبدلاً من محاولة المواكبة ، يمكنك التعمق في الأمر.

manfreed لا يطلب الناس لعبة جديدة لامعة ، لكنهم يطالبون بتصحيح خطأ في تصميم إطار العمل. في الوقت الحالي ، نضطر أحيانًا إلى استخدام العناصر القابلة للملاحظة ، وفي بعض الأحيان غير قادرين على استخدام العناصر القابلة للملاحظة ، للوظائف الرئيسية. أولئك الذين يكرهون ما يمكن ملاحظته يشعرون بالإحباط. أولئك الذين يحبون ما يمكن ملاحظته محبطون. وقد أصيب الكثير منا بخيبة أمل شديدة بسبب الموقف الذي استسلمناه وانتقلنا إلى أطر أخرى. كنت أرغب في الاستمرار في استخدام Angular ، قليلاً من التوجيه وكان يمكن أن يكون إطارًا رائعًا حقًا. لكن منشورات المدونات حول سوء الإدارة ، والافتقار إلى البراغماتية ، والإغفالات ، كلها مخيبة للآمال بشكل موضوعي.

insidewhy تحلى بالصبر ، فهناك دائمًا بعض القمم والوديان على الطريق ، لكن هذا لا يعني أن الآخرين لا

لم يكن هناك أي ذكر لأي قضية معينة مذكورة أعلاه في خارطة الطريق ، الأمر الذي وجدته محزنًا ، كنت آمل حقًا أن يكون هناك شيء ما ، أو ذكر ، أو إقرار ... هذه المناقشة تبعها الخلاف الزاوي -

image

أعطيتهم ميزة الشك وسألت في التعليق على مقالة خارطة الطريق المتوسطة ، رد مينكو:

image

لقد كرر إلى حد كبير ما قاله هنا قبل بضعة أشهر ، ولم يتم إصلاح أي من هذه المشكلات المتعلقة بـ rxjs في أي وقت قريب ، لذا نعم.

لقد انتهيت من محاولة إيصال وجهة نظري ، ولكن دعني أحاول مرة أخيرة .. لا أطلب تحويل Angular إلى Cycle.js ، لتحل محل واجهات برمجة التطبيقات الحالية ، كل ما أطلبه هو ثلاث

  • دورة حياة يمكن ملاحظتها
  • مدخلات يمكن ملاحظتها
  • أحداث القالب التي يمكن ملاحظتها

لا شيء من هذا يكسر التوافق مع الإصدارات السابقة ، ويزيد منحنى التعلم ، ولا يتماشى مع واجهات برمجة التطبيقات الأخرى ويمكنني أن أتخيل أنه لا يؤثر على الأداء ، لذا فقط كيف أنها صعبة للغاية وتتطلب تخطيطًا أطول ودقيقًا ، مقارنة بالمهام الأخرى التي تنتظرنا على أي حال. فقط أضف واحدًا في ذلك الوقت ، أظهر أنك تهتم. لو سمحت.

fxck : +1: بالتأكيد.

  • دورة حياة يمكن ملاحظتها
  • مدخلات يمكن ملاحظتها
  • أحداث القالب التي يمكن ملاحظتها

insidewhy كن صبورا

إن طلب الصبر لأكثر من 5 سنوات ليس بالأمر الواقعي عندما يكون هناك الكثير من المنافسين الذين يمرون في السباق ويتنافسون جميعًا على جذب الانتباه.

@ insidewhy كان من المفترض بشكل عام.

fxck تمتلك Google (حسب آخر ومتشابه للغاية في طبيعته ، ويعد التبديل بين هذه المشاريع ومراجعة الأقران (أتخيل) سلسًا للغاية. حتى في شركتي ، تتمثل إحدى الفوائد الهائلة لـ Angular في أنه بدون أن أراجع حتى كود فريق آخر ، أعلم أنه في حالة لا تؤدي فيها مراجعة الأقران إلى إطلاق تحقيق كامل.

لنفترض الآن أننا قمنا بتنفيذ كل اختصار من اختصارات RxJS المفيدة في النواة ، فماذا يحدث بعد ذلك؟ من الممكن أن ينتهي بنا الأمر بتحيز إجرائي مقابل تحيز تفاعلي ، دون توجيه واضح بشأن التحيز الصحيح لأي حالة معينة. بعد قراءة المناقشات حتى الآن ، فإن إجابة الفريق الزاوي ليست "هذه أولوية منخفضة" (كما يوحي التدفق الخاص بك) ، يبدو في الواقع أقرب إلى "لا نريد الانحياز إلى جانب".

مستخدمو RxJS المتقدمون في مجتمع Angular هنا هم أقلية صوتية ، لأنه بعد أن تقوم بمكتبات Grok Typescript ، و DI ، و Templating ، و Angular المتنوعة ، لديك ما يقرب من عام واحد تحت حزامك باستخدام إطار العمل يوميًا ، وأنت الآن جاهز لفهم RxJS تمامًا. إن السماح للأشخاص رفيعي المستوى بالانفصال عن التحيز التفاعلي في مراجعات الأقران يجعل الناس أكثر تنفرًا ، وهذا حرفيًا آخر شيء يحتاجه Angular.

هدف Angular (كما أراه) هو تقليل المحادثات وضبطها بعيدًا عن "استخدام تقنية X لأنها أفضل ، وهنا رواية قصيرة لماذا" والاحتفاظ بالمحادثات في مراجعات الأقران حول منطق الأعمال الذي يتم تنفيذه. هل نريد حقًا تقسيم مكوناتنا بين الزاوية "المتقدمة" والزاوية "المبتدئة" أكثر مما لدينا بالفعل؟

يمكن القول إن هذه هي نفس الحجج التي رأيناها مع إدارة الدولة ، فلماذا يجب أن تحدد Angular من الأنماط العديدة الممكنة أيها صحيح؟

اسمحوا لي فقط أن أقتبس من أحد أعضاء الفريق الزاوي من أجلك.

image

بالمناسبة ، لا يوجد شيء متقدم على الإطلاق بشأن أي من هذه (دورة الحياة التي يمكن ملاحظتها ، والمدخلات التي يمكن ملاحظتها ، وأحداث النماذج التي يمكن ملاحظتها).

يمكن القول إن هذه هي نفس الحجج التي رأيناها مع إدارة الدولة ، فلماذا يجب أن تحدد Angular من الأنماط العديدة الممكنة أيها صحيح؟

الفرق بين إدارة الدولة وهذا ، هو أن إدارة الدولة يمكن أن يقوم بها المجتمع ، ولا يوجد شيء داخل النواة الزاوي يمنعها. لسوء الحظ ، لا يوفر Angular طرقًا لتنفيذ أي من هؤلاء الثلاثة الذين ذكرتهم بشكل صحيح . (تحرير: تصحيح الارتباط للتعليق)

أنا من صميم قلبي لترك أكبر قدر ممكن للمجتمع ، والذي يتضمن حزم مثل النماذج ، وجهاز التوجيه ، والتخطيط المرن ، والعالمية ، وما إلى ذلك ، دع فريق Angular يركز على العناصر الأساسية و cli والمكونات. ولكن من أجل ذلك يحتاجون إلى تزويد المجتمع بنقاط دخول كافية ، على سبيل المثال السماح بمكونات ذات ترتيب أعلى . لكنهم فشلوا في القيام بذلك لسنوات (في كثير من الأحيان يقولون إن Ivy مطلوب أولاً) ويرفضون الاعتراف / الحديث عن هذا في خططهم الآن.

بعد قراءة المناقشات حتى الآن ، فإن إجابة الفريق الزاوي ليست "هذه أولوية منخفضة" (كما يوحي التدفق الخاص بك) ، يبدو في الواقع أقرب إلى "لا نريد الانحياز إلى جانب".

نعم وهذا مخيف.

fxck أعتقد أننا على نفس الصفحة حول هذا الموضوع. أود أن أقول أنه في كل مرة أقوم بإحضار RxJS في المنتديات أو حتى مع زملائي المهندسين ، فإن معظم الاقتباسات التي يمكنني الاستشهاد بها هي "ما زلت لا أفهم هذا ، كيف يمكنني معرفة المزيد؟" أو "أجد أنه من الصعب تحديد عدد المشغلين." أو "أواجه مشكلة في قراءة خط الأنابيب هذا في هذه العلاقات العامة". لكل مهندس RxJS متمرس جيدًا ، يبدو أن هناك 15 مهندسًا زاويًا على دراية جيدة بحواجب مجعدة.

نعم وهذا مخيف.

هذا شكل زائد قليلاً ، فنحن لا "نحتاج" إلى @angular/core للحصول على هذه الأنماط ، في الواقع هناك العديد من المتغيرات والمكتبات داخل هذه المشكلة والتي يمكن استخدامها اليوم في أي مشروع. التحفظ الوحيد في استخدام الخيارات المذكورة سابقًا هو أنه قد يتعين عليك في المستقبل الانتقال إلى شيء توفره Angular كبديل قياسي @angular/core . هل حقا أن من الصعب بالنسبة لنا ل npm uninstall وإصلاح كافة الأخطاء نسخة مطبوعة على الآلة الكاتبة؟

القرارات المعمارية الكبرى ، التي تؤثر على جميع المشاريع الزاوية ، وتتطلب ساعات لا حصر لها للتوثيق والترحيل إذا لم تنجح ، بالنسبة لي يبدو الأمر مخيفًا أكثر ، وقد كنا هناك من قبل:

هذا القليل من القطع الزائد ، لسنا "بحاجة" إلى @ الزاوي / النواة للحصول على هذه الأنماط ، في الواقع هناك العديد من المتغيرات والمكتبات في هذه المشكلة والتي يمكن استخدامها اليوم في أي مشروع.

لا ، ليس كل حل يتطلب اختراقًا أو يعتمد على واجهات برمجة التطبيقات الداخلية التي يمكن أن تتغير. هذا هو بيت القصيد .. اقرأ ما قاله insidewhy https://github.com/angular/angular/issues/5689#issuecomment -630661006 وما قلته أدناه حول تدفقات حدث القالب.

// تحرير الرابط المصحح للتعليق

لا ، ليس كل حل يتطلب اختراقًا أو يعتمد على واجهات برمجة التطبيقات الداخلية التي يمكن أن تتغير.

ما هي واجهات برمجة التطبيقات أو الأنواع الداخلية التي تعتقد أنه يجب أن تكون عامة / عامة للسماح للمجتمع بمعالجة ذلك؟ إذا كان هذا التصميم في نمط تعليق لأنه لا يوجد مسار واضح للمضي قدمًا ، فيبدو من المناسب أن نطلب أن يُسمح لنا بتصميم أسطوانة خاصة بنا بدلاً من قرع نفس الأسطوانة باستمرار.

اقرأ التعليق الآخر الذي كتبهinsidewhy ، لقد حاول القيام بذلك داخل النواة.

image

fxck لن أناقش تاريخ محاولات تنفيذ هذا في جوهره أو كيف ظلت هذه القضية مفتوحة لمدة 5 سنوات ، ما الذي يمنعنا الآن من فتح الأجزاء الداخلية للسماح للمجتمع بتطوير التصميم بأنفسهم؟

Yoinsidewhy ، أتساءل عما إذا كان هذا هو نوع التحقق من الاختراق الذي يعتمد عليه lib الخاص بك. يبدو أنه لم يعد يعمل باستخدام TS 4.0

تم استخدام الخاصية "serviceStackId $" قبل التهيئة الخاصة بها (2729)

image

Yoinsidewhy ، أتساءل عما إذا كان هذا هو نوع التحقق من الاختراق الذي يعتمد عليه lib الخاص بك. يبدو أنه لم يعد يعمل باستخدام TS 4.0

لا ، لقد كان في مترجم القالب. هذا شيء آخر. اللعنة. آه حسنا. يمكنني إضافتك إلى قائمة المشرف إذا كنت تريد محاولة إصلاحها.

fxck في الواقع ، يجب عليك تعيين عامل الأنابيب هذا في ngOnInit نظرًا لأن الخصائص القائمة على التزيين لن يتم إدخالها إلا بعد تشغيل المُنشئ ، لذلك فهذه في الواقع مشكلة مشروعة في التعليمات البرمجية الخاصة بك.

insidewhy لقد هذا ،

function ObservableInput() {
  return (target: any, propertyKey: any) => {
    Object.defineProperty(target, propertyKey, {
      set(value: any) {
        console.log(target, propertyKey, value);
      },
      get() {
        return 'ObservableInput modified value';
      },
    })
  }
}

class Foo {
    @ObservableInput()
    bar = 'original bar value';

    baz = this.bar;

    constructor() {
        console.log('loggging this.baz', this.baz);
    }
}

new Foo();

يسجل

loggging this.baz ObservableInput القيمة المعدلة

لذلك أعتقد أنه لا يزال يجب أن يعمل ، فقط في TS4 ، يشتكي المترجم لأنه لا يدرك أن هناك get مع قيمة داخل ذلك المصمم ..

أنا أستخدم مصمم ديكور لاستشعار تغيير عنصر الإدخال وعمل نسخة يمكن ملاحظتها من دعامة الإدخال. انظر هذه الرموز واندبوكس التجريبي .

هذه هي الطريقة التي يعمل بها:

// subjectize.ts
export function Subjectize(keyToWatch: string): PropertyDecorator {
  return (proto: any, propKey: string) => {
    const internalKey = Symbol(keyToWatch);
    Object.defineProperties(proto, {
      [keyToWatch]: {
        get() {
          return this[internalKey];
        },
        set(value) {
          this[internalKey] = value;
          this[propKey].next(value);
        }
      }
    });
  };
}
// counter.component.ts
import { Component, Input } from "@angular/core";
import { ReplaySubject } from "rxjs";
import { Subjectize } from "./subjectize";

@Component({
  selector: "app-counter",
  templateUrl: "./counter.component.html",
  styleUrls: []
})
export class CounterComponent {
  @Input()
  count: number;

  @Subjectize("count")
  count$ = new ReplaySubject(1);
}

كما أشار wmaurer ، يمكن معاملة @Subjectize كـ "سكر" لإنجاز الأمور.

يجدر قراءة الدليل الرسمي لـ angular's Intercept input property changes باستخدام أداة ضبط ، وهو ما يوضح أنه يمكننا الشعور بتغييرات الإدخال باستخدام getter/setter .

hankchiutw يبدو هذا الحل مشابهًا @BindObservable : https://github.com/PSanetra/bind-observable#usage

شكراhankchiutw

نظرًا لأنك تقوم بتهيئة ReplaySubject بـ 1 ، فقد اخترت استخدام BehaviorSubject بدلاً من ذلك.
كما أنني قمت بتهيئة القيمة مباشرة في الموضوع.

export function Subjectize<T>(keyToWatch: string): PropertyDecorator {
  return (target: Object, propKey: string) => {
    const internalKey = Symbol(keyToWatch);
    Object.defineProperties(target, {
      [keyToWatch]: {
        get(): T {
          return this[internalKey];
        },
        set(value: T) {
          this[internalKey] = value;

          if (this[propKey]) {
            this[propKey].next(value);
          } else {
            this[propKey] = new BehaviorSubject(value);
          }
        }
      }
    });
  };
}

@Component({
    changeDetection: ChangeDetectionStrategy.OnPush,
    selector: 'rol-bla',
    templateUrl: 'bla.html',
    styleUrls: [ 'bla.scss' ]
})
export class BlaComponent implements OnInit {
    @Input() world: World;
    @Subjectize<World>('world') world$: BehaviorSubject<World>;

    // ...
}

أتمنى أن أتمكن من تجنب كتابة النوع على خاصية "Subjectized" لأنه يجب أن يكون قادرًا على تخمينه من الخاصية ذات الصلة :( هل لديك فكرة عن كيفية القيام بذلك؟

سيكون الحلم أن تكون قادرًا على القيام بذلك وإنشاء خاصية الموضوع ذات الصلة تلقائيًا (العالم $ في حالتي) كموضوع السلوكومهيأ بشكل صحيح.

export class BlaComponent implements OnInit {
    @Input() @Subjectize() world: World;

    // ...
}

mparpaillon التصميم المقترح هو إلى حد كبير كيف يتم تنفيذه في https://github.com/PSanetra/bind-observable
الاختلاف الوحيد هو أن المصمم @BindObservable() يستخدم ReplaySubject تحت الغطاء. لذلك إذا كنت تريد أن يحتوي هذا الموضوع على قيمة أولية ، فأنت بحاجة أيضًا إلى تهيئة الخاصية المرتبطة بشكل صريح (أيضًا إذا كانت غير معرَّفة فقط ، فقد يكون من الممكن ألا يسمح نوع الخاصية بقيم غير معرَّفة أو فارغة).

مثال Stackblitz

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class MyComponentComponent {
  @Input()
  @BindObservable()
  counter: number;
  counter$: ReplaySubject<number>;
}

شكرًا PSanetra لكني أفضل الحل الخاص بي (وهو في الواقع حل Hank)

mparpaillon لقد جربت شيئًا ما لحلمك (ha) في عرض توضيحي آخر .

يبدو الاستخدام

export class CounterComponent {
  @Input()
  @Subjectize()
  count: number;

  @Input()
  @Subjectize("myCount$")
  anotherCount: number;
}

حيث يمكنك اختيار تحديد اسم الدعامة الخاضع لها.

على الرغم من أنه ممكن تقنيًا ، إلا أنني أخشى أن يكون ذلك غامضًا بالنسبة للمطورين (نظرًا لأن عضوًا جديدًا في الفصل تم إنشاؤه underhood).

شكرا hankchiutw ! لا يبدو أن المطبوع يسمح لي باستخدام count $ أو myCount $ بالرغم من ذلك.

Capture d’écran 2020-11-12 à 10 11 50

كما قد تكون محقًا بشأن الغموض ... شكرًا مرة أخرى

لا يبدو أن المطبوع يسمح لي باستخدام count $ أو myCount $ بالرغم من ذلك.

لقد أعلنت أن أعضاء صفك "count" و "anotherCount" ، لهذا السبب لا يمكنك الوصول إلى "myCount $" و "count $". إنها ببساطة غير موجودة ، لأنك لم تعلن عنها في أي مكان.

أعلم ... هذا هو بيت القصيد. كنت أبحث عن طريقة لأعلنها من مصمم الديكور. عرض hankchiutw حلاً وأنا أقول أنه لا يعمل كما هو

mparpaillon ألق نظرة على الحل الخاص بي: https://github.com/Futhark/ngx-observable-input

Futhark أوه هذا ساخن! شكرا

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات