Aurelia مقابل Angular 2 - مقارنة كود
نشرت: 2022-03-11Angular و Aurelia ، أحفاد JavaScript Angular 1 القديمة الجيدة ، هم منافسين شرسين ، تم تطويرهما وإصدارهما في نفس الوقت تقريبًا وبفلسفة مماثلة ، لكنهما يختلفان في عدد من الطرق الرئيسية. في هذه المقالة ، سنفعل مقارنات جنبًا إلى جنب لتلك الاختلافات في الميزات والتعليمات البرمجية.
قصة قصيرة طويلة ، تم إنشاء Aurelia بواسطة Rob Eisenberg ، المعروف باسم مبتكر Durandal و Caliburn. لقد عمل في فريق Angular 2 في Google لكنه غادر في عام 2014 عندما اختلفت وجهات نظره حول كيفية ظهور إطار العمل الحديث عن آرائهم.
تستمر أوجه التشابه على مستوى أكثر تقنية أيضًا: تعتبر القوالب والمكونات (أو العناصر المخصصة) المرتبطة بها أساسية لكل من تطبيقات Angular و Aurelia ، وكلاهما يتطلب أن يكون لديك مكون جذر (أي التطبيق). علاوة على ذلك ، يستخدم كل من Angular و Aurelia بكثرة أدوات الزخرفة لتكوين المكونات. كل مكون له دورة حياة ثابتة يمكننا ربطها.
إذن ما الفرق بين Aurelia و Angular 2؟
الاختلاف الرئيسي ، وفقًا لروب أيزنبرغ ، يكمن في الكود: أوريليا غير مزعجة. عند تطوير تطبيق Aurelia (بعد التكوين) ، فإنك تكتب في ES6 أو TypeScript ، وتبدو القوالب مثل HTML عاقل تمامًا ، خاصة عند مقارنتها بـ Angular. Aurelia هي اتفاقية أكثر من التكوين ، و 95٪ من الوقت ستكون على ما يرام باستخدام الاصطلاحات الافتراضية (مثل تسمية القالب ، وتسمية العناصر ، وما إلى ذلك) ، بينما يتطلب Angular منك توفير التكوين لكل شيء بشكل أساسي.
تعتبر Aurelia أيضًا أكثر توافقًا مع المعايير ، فقط لأنها ليست حساسة لحالة الأحرف عندما يتعلق الأمر بعلامات HTML ، بينما Angular 2 كذلك. هذا يعني أن Angular 2 لا يمكنها الاعتماد على محلل HTML للمتصفح ، لذلك قاموا بإنشاء المحلل اللغوي الخاص بهم.
عامل آخر يجب مراعاته عند الاختيار بين أطر عمل SPA هو المجتمع - النظام البيئي - من حولهم. يحتوي كل من Angular و Aurelia على جميع الأساسيات (جهاز التوجيه ، ومحرك القالب ، والتحقق من الصحة ، وما إلى ذلك) ، ومن السهل الحصول على نموذج أصلي أو استخدام مكتبة تابعة لجهات خارجية ، ولكن ليس من المستغرب أن Angular لديها مجتمع أكبر وتطور أكبر فريق.
علاوة على ذلك ، في حين أن كلا الإطارين مفتوحان المصدر ، تم تطوير Angular بشكل أساسي بواسطة Google وليس الغرض منه تسويقه بينما Durandal، Inc. ، التي توظف الفريق الأساسي ، تتبع نموذج Ember.js لتحقيق الدخل من خلال الاستشارات والتدريب.
Aurelia مقابل Angular: مقارنة كود
لنلقِ نظرة على بعض أبرز الميزات التي تبرز الفلسفات الكامنة وراء كل إطار عمل.
بعد استنساخ المشاريع الأولية لـ Angular و Aurelia ، لدينا تطبيق ES6 Aurelia (يمكنك استخدام Jspm / System.js و Webpack و RequireJS بالاشتراك مع ES6 أو TypeScript) وتطبيق TypeScript Angular (WebPack) ، على التوالي.
دعنا نلف.
ربط البيانات
قبل أن نقارن أمثلة العمل جنبًا إلى جنب ، علينا أن نلقي نظرة على بعض الاختلافات النحوية بين Aurelia و Angular 2 ، أي في الوظيفة الرئيسية لقيم الربط من وحدة التحكم إلى العرض. استخدم Angular 1 "الفحص القذر" لكل شيء ، وهي طريقة تمسح نطاق التغييرات. هذا ، لأسباب مفهومة ، تسبب في عدد من مشاكل الأداء. لم يتبع Angular 2 ولا Aurelia هذا المسار. بدلاً من ذلك ، يستخدمون ربط الحدث.
ربط البيانات في الزاوية 2
في Angular ، يمكنك ربط البيانات بأقواس مربعة واستخدام الأقواس لربط الأحداث ، مثل:
<element [property]="value"></a> <element (someEvent)="eventHandler($event)"></a>
الربط ثنائي الاتجاه - عندما تريد أن تنعكس التغييرات في بيانات التطبيق على طريقة العرض والعكس بالعكس - هو مزيج من الأقواس المربعة والأقواس. لذلك ، بالنسبة للإدخال ثنائي الاتجاه ، سيعمل هذا بشكل جيد:
<input type="text" [(ngModel)]="text"> {{text}}
بمعنى آخر ، تمثل الأقواس حدثًا بينما تمثل الأقواس المربعة قيمة يتم دفعها للإدخال.
قام فريق Angular بعمل رائع في فصل الاتجاهات الملزمة: إلى DOM ، من DOM ، والاتجاه ثنائي الاتجاه. هناك أيضًا الكثير من السكر النحوي المتعلق بفئات وأنماط الربط. ضع في اعتبارك ، على سبيل المثال ، المقتطف التالي كمثال للربط أحادي الاتجاه:
<div [class.red-container]="isRed"></div> <div [style.width.px]="elementWidth"></div>
ولكن ماذا لو أردنا ربط البيانات ثنائية الاتجاه في مكون؟ ضع في اعتبارك إعداد الإدخال الأساسي التالي:
<!-- parent component --> <input type="text" [(ngModel)]="text"> {{ text }} <my-component [(text)]="text"></my-component> import {Component, Input} from '@angular/core'; @Component(/* ... */) export class MyComponent { @Input() text : string; } <!-- child component --> <input [(ngModel)]="text"> Text in child: {{ text }}
لاحظ أنه لاستخدام ngModel
، يجب أن تستورد الوحدة النمطية الخاصة بك FormsModule من @angular/forms
Forms. الآن لدينا شيء مثير للاهتمام. يؤدي تحديث القيمة في الإدخال الرئيسي إلى تغيير القيم في كل مكان ، ولكن تعديل إدخال الطفل يؤثر فقط على ذلك الطفل. إذا أردنا تحديث القيمة الأصلية ، فنحن بحاجة إلى حدث لإعلام الوالدين. اصطلاح التسمية لهذا الحدث هو property name + 'Change'
، على النحو التالي:
import {Component, Input, Output, EventEmitter} from '@angular/core'; @Component(/* ... */) export class MyComponent { @Input() text : string; @Output() textChange = new EventEmitter(); triggerUpdate() { this.textChange.emit(this.text); } }
يبدأ الربط ثنائي الاتجاه بشكل صحيح بعد الارتباط بحدث ngModelChange
:
<!-- child component --> <input [(ngModel)]="text" (ngModelChange)="triggerUpdate($event)">
ماذا عن الربط لمرة واحدة ، عندما تخبر الإطار بشكل فعال أن يتجاهل القيم المقيدة حتى لو تغيرت؟
في Angular 1 ، استخدمنا {{:: value}} للربط مرة واحدة. في Angular 2 ، يصبح الربط لمرة واحدة معقدًا: تشير الوثائق إلى أنه يمكنك استخدام changeDetection: ChangeDetectionStrategy.OnPush
السمة في تكوين المكون ، ولكن هذا سيجعل جميع عمليات الربط لمرة واحدة.
ربط البيانات: طريقة أوريليا
على عكس Angular 2 ، فإن ربط البيانات والأحداث في Aurelia بسيط حقًا. يمكنك استخدام إما الاستيفاء ، تمامًا مثل property="${value}"
، أو استخدام أحد أنواع الربط التالية:
property.one-time="value" property.one-way="value" property.two-way="value"
الأسماء لا تحتاج إلى شرح. علاوة على ذلك ، هناك property.bind="value"
، وهي عبارة عن سكر نحوي يكتشف ذاتيًا ما إذا كان يجب أن يكون الربط أحادي الاتجاه أو ثنائي الاتجاه. انصح:
<!-- parent--> <template bindable="text"> <input type="text" value.bind="text"/> <child text.two-way="text"></child> </template> <!-- child custom element --> <template bindable="text"> <input type="text" value.bind="text"/> </template>
في المقتطف أعلاه ، يمكن تكوين كل من @bindable
و @Input
، بحيث يمكنك بسهولة تغيير أشياء مثل اسم الخاصية التي يتم ربطها ، وما إلى ذلك.
ماذا عن الأحداث؟ للربط بالأحداث في Aurelia ، يمكنك استخدام .trigger
و .delegate
. على سبيل المثال ، لجعل المكون الفرعي يطلق حدثًا ، يمكنك القيام بما يلي:
// child.js this.element.dispatchEvent(new CustomEvent('change', { detail: someDetails }));
ثم للاستماع إلى ذلك في الوالد:
<child change.trigger="myChangeHandler($event)"></child> <!-- or --> <child change.delegate="myChangeHandler($event)"></child>
الفرق بين هذين العنصرين هو أن .trigger
ينشئ معالج حدث على هذا العنصر المحدد بينما يضيف .delegate
مستمعًا على document
. هذا يوفر الموارد ، لكن من الواضح أنه لن ينجح مع الأحداث غير الفقاعية.
مثال أساسي على Aurelia مقابل Angular
الآن بعد أن غطينا الربط ، دعنا ننشئ مكونًا أساسيًا يعرض رسمًا متجهًا قابلًا للتطوير (SVG). سيكون رائعًا ، لذلك awesome-svg
. سيوضح هذا التمرين كلاً من الوظائف الأساسية والفلسفة لـ Aurelia و Angular 2. تتوفر أمثلة كود Aurelia لهذه المقالة على GitHub.
مثال مستطيلات SVG في Aurelia
لنقم أولاً ببناء ملف JavaScript:
// awesome-svg.js import {bindable} from 'aurelia-framework'; export class AwesomeSvgCustomElement { @bindable title; @bindable colors = []; }
الآن من أجل HTML.
في Aurelia ، يمكنك تحديد القالب (أو استخدام القالب المضمن) مع التعليقات التوضيحية @inlineView
@template
حتى @noView
، ولكن خارج المربع ، يبحث عن ملف .html
بنفس اسم ملف .js
ملف. وينطبق الشيء نفسه على اسم العنصر المخصص - يمكنك تعيينه باستخدام @customElement('awesome-svg')
، ولكن إذا لم تقم بذلك ، فستقوم Aurelia بتحويل العنوان إلى dash-case وتبحث عن تطابق.
نظرًا لأننا لم نحدد خلاف ذلك ، فسيتم استدعاء العنصر awesome-svg
وستبحث Aurelia عن القالب الذي يحمل نفس اسم ملف js
( awesome-svg.html
) في نفس الدليل:
<!-- awesome-svg.html --> <template> <h1>${title}</h1> <svg> <rect repeat.for="color of colors" fill.bind="color" x.bind="$index * 100" y="0" width="50" height="50"></rect> </svg> </template>
لاحظ علامة <template>
؟ يجب تغليف جميع القوالب بعلامة <template>
. ومن الجدير بالملاحظة أيضًا أنك تستخدم "for… of and the string interpolation
$ {title} `تمامًا كما تفعل في ES6.
الآن لاستخدام المكوِّن ، يجب علينا إما استيراده في قالب بـ <require from="path/to/awesome-svg"></require>
أو ، إذا تم استخدامه عبر التطبيق ، فقم بتعميم المورد في وظيفة تكوين إطار العمل باستخدام aurelia.use.globalResources('path/to/awesome-svg');
، والتي ستستورد المكون awesome-svg
مرة واحدة وإلى الأبد.
[ملاحظة ، إذا لم تفعل أيًا من هذين الأمرين ، فسيتم التعامل مع <awesome-svg></awesome-svg>
تمامًا مثل أي علامة HTML أخرى ، بدون أخطاء.]
يمكنك عرض المكون مع:
<awesome-svg colors.bind="['#ff0000', '#00ff00', '#0000ff']"></awesome-svg>
يؤدي هذا إلى عرض مجموعة من 3 مستطيلات:
مثال مستطيلات SVG في الزاوية 2
لنقم الآن بالمثال نفسه في Angular 2 ، المتوفر أيضًا على GitHub. يتطلب Angular 2 تحديد كل من القالب واسم العنصر:
// awesome-svg.component.ts import {Component, Input} from '@angular/core'; @Component({ selector: 'awesome-svg', templateUrl: './awesome-svg.component.html' }) export class AwesomeSvgComponent { @Input() title : string; @Input() colors : string[] = [] }
المنظر هو المكان الذي تصبح فيه الأمور معقدة بعض الشيء. بادئ ذي بدء ، يتعامل Angular بصمت مع علامات HTML غير المعروفة بالطريقة نفسها التي يتعامل بها المتصفح: فهو يطلق خطأ يقول أن شيئًا ما على غرار my-own-tag
هو عنصر غير معروف. إنه يفعل الشيء نفسه مع أي خصائص تربطها ، لذلك إذا كان لديك خطأ مطبعي في مكان ما في الكود ، فسوف يجذب انتباهًا كبيرًا لأن التطبيق سيتعطل. تبدو جيدة ، أليس كذلك؟ نعم ، لأنك ستلاحظ على الفور إذا كسرت التطبيق ، ولا ، لأن هذا مجرد شكل سيء.
ضع في اعتبارك هذا المقتطف ، وهو جيد تمامًا من حيث بناء جملة الربط:
<svg> <rect [fill]="color"></rect> </svg>
على الرغم من أنه يقرأ جيدًا ، ستحصل على خطأ مثل "لا يمكن الربط بـ" ملء "نظرًا لأنها ليست خاصية معروفة لـ": svg: rect "." لإصلاح ذلك ، تحتاج إلى استخدام بناء الجملة [attr.fill]="color"
بدلاً من ذلك. لاحظ أيضًا أنه يلزم تحديد مساحة الاسم في العناصر الفرعية داخل <svg/>: <svg:rect>
للسماح لـ Angular بمعرفة أنه لا يجب التعامل معها على أنها HTML. دعنا نوسع المقتطف الخاص بنا:
<!-- awesome-svg.component.html--> <h1>{{ title }}</h1> <svg> <rect *ngFor="let color of colors; let i = index" [attr.fill]="color" [attr.x]="i * 100" y="0" width="50" height="50" ></rect> </svg>
هناك نذهب. بعد ذلك ، قم باستيراده في تكوين الوحدة:
@NgModule({ declarations: [ AwesomeSvgComponent ] //... })
الآن يمكن استخدام المكون عبر هذه الوحدة ، مثل:

<awesome-svg [colors]="['#ff0000', '#00ff00', '#0000ff']" title="Rectangles"></awesome-svg>
العناصر المخصصة
لنفترض الآن أننا نريد أن يكون كود المستطيل الخاص بنا مكونًا مخصصًا بمنطقه الخاص.
العناصر المخصصة: الطريق الزاوي 2
نظرًا لأن Angular 2 تعرض المكونات بما يتوافق مع محددها المحدد ، فمن السهل جدًا تحديد مكون مخصص ، مثل:
@Component({ selector: 'g[custom-rect]', ... })
سيعرض المقتطف أعلاه العنصر المخصص لأي علامات <g custom-rect></div>
، وهو أمر سهل للغاية.
العناصر المخصصة: طريقة أوريليا
تتيح لنا Aurelia إنشاء عناصر مخصصة للقالب فقط:
<template bindable="colors, title"> <h1>${title}</h1> <svg> <rect repeat.for="color of colors" fill.bind="color" x.bind="$index * 100" y="0" width="50" height="50"></rect> </svg> </template>
سيتم تسمية العنصر المخصص وفقًا لاسم الملف. الاختلاف الوحيد عن تسمية المكونات الأخرى هو أنه عند الاستيراد ، سواء في التكوين أو عبر علامة <require>
، يجب أن تضع .html
في النهاية. على سبيل المثال: <require from="awesome-svg.html"></require>
.
تحتوي Aurelia أيضًا على سمات مخصصة ، لكنها لا تخدم نفس الغرض كما في Angular 2. على سبيل المثال ، في Aurelia ، يمكنك استخدام التعليق التوضيحي @containerless
على عنصر rect
مخصص. يمكن أيضًا استخدامcontainerless مع قوالب مخصصة بدون وحدة التحكم و <compose>
@containerless
والتي تعرض الأشياء بشكل أساسي في DOM.
ضع في اعتبارك الكود التالي الذي يحتوي على التعليق التوضيحي @containerless
:
<svg> <custom-rect containerless></custom-rect> </svg>
لن يحتوي الإخراج على علامة العنصر المخصص ( custom-rect
) ، ولكن بدلاً من ذلك نحصل على:
<svg> <rect ...></rect> </svg>
خدمات
فيما يتعلق بالخدمات ، فإن Aurelia و Angular متشابهة جدًا ، كما سترى في الأمثلة التالية. افترض أننا بحاجة إلى NumberOperator
الذي يعتمد على NumberGenerator
.
خدمات في أوريليا
إليك كيفية تحديد خدمتنا في Aurelia:
import {inject} from 'aurelia-framework'; import {NumberGenerator} from './number-generator' export class NumberGenerator { getNumber(){ return 42; } } @inject(NumberGenerator) export class NumberOperator { constructor(numberGenerator){ this.numberGenerator = numberGenerator; this.counter = 0; } getNumber(){ return this.numberGenerator.getNumber() + this.counter++; } }
الآن ، بالنسبة للمكون ، نقوم بحقنه بنفس الطريقة:
import {inject} from 'aurelia-framework'; import {NumberOperator} from './_services/number-operator'; @inject(NumberOperator) export class SomeCustomElement { constructor(numberOperator){ this.numberOperator = numberOperator; //this.numberOperator.getNumber(); } }
كما ترى ، مع حقن التبعية ، يمكن لأي فئة أن تكون خدمة قابلة للتوسيع بالكامل ، لذا يمكنك حتى كتابة أدوات الحل الخاصة بك.
مصانع في أوريليا
إذا كان ما تحتاجه هو مصنع أو مثيل جديد ( Factory
و NewInstance
هما مجرد بضعة أدوات حل شائعة يتم توفيرها خارج الصندوق) ، يمكنك القيام بما يلي:
import { Factory, NewInstance } from 'aurelia-framework'; @inject(SomeService) export class Stuff { constructor(someService, config){ this.someService = someService; } } @inject(Factory.of(Stuff), NewInstance.of(AnotherService)) export class SomethingUsingStuff { constructor(stuffFactory, anotherService){ this.stuff = stuffFactory(config); this.anotherServiceNewInstance = anotherService; } }
خدمات الزاوي
إليك نفس مجموعة الخدمات في Angular 2:
import { Injectable } from '@angular/core'; import { NumberGenerator } from './number-generator'; @Injectable() export class NumberGenerator { getNumber(){ return 42; } } @Injectable() export class NumberOperator { counter : number = 0; constructor(@Inject(NumberGenerator) private numberGenerator) { } getNumber(){ return this.numberGenerator.getNumber() + this.counter++; } }
التعليق التوضيحي @Injectable
مطلوب ، ولإدخال خدمة فعليًا ، تحتاج إلى تحديد الخدمة في قائمة الموفرين في تكوين المكون أو تكوين الوحدة النمطية بالكامل ، مثل:
@Component({ //... providers: [NumberOperator, NumberGenerator] })
أو ، غير مستحسن ، يمكنك أيضًا تحديده في bootstrap(AppComponent, [NumberGenerator, NumberOperator])
.
لاحظ أنك تحتاج إلى تحديد كل من NumberOperator
و NumberGenerator
، بغض النظر عن كيفية حقنه.
سيبدو المكون الناتج كما يلي:
@Component({ //... providers: [NumberOperator, NumberGenerator], }) export class SomeComponent { constructor(@Inject(NumberOperator) public service){ //service.getNumber(); } }
المصانع في Angular 2
في Angular 2 ، يمكنك إنشاء مصانع باستخدام التعليق التوضيحي المقدم ، والذي يتم استخدامه أيضًا لتسمية provide
لمنع تضارب الأسماء. قد يبدو إنشاء مصنع كما يلي:
let stuffFactory = (someService: SomeService) => { return new Stuff(someService); } @Component({ //... providers: [provide(Stuff, {useFactory: stuffFactory, deps: [SomeService]})] })
التحويل
Angular 1 لديه القدرة على تضمين المحتوى ، "فتحة" ، من قالب إلى آخر باستخدام التحويل. دعونا نرى ما يقدمه أحفاده.
إسقاط المحتوى مع Angular 2
في Angular 2 ، يُطلق على التحويل اسم "إسقاط المحتوى" ، وهو يعمل بنفس الطريقة التي يعمل بها ng-transclude
؛ على سبيل المثال ، عند التحدث بلغة Angular 1 ، فإن المحتوى المشمول يستخدم النطاق الأصلي. سوف تتطابق مع علامة المحتوى المشتملة على أساس محدد التكوين. انصح:
@Component({ selector: 'child', template: `Transcluded: <ng-content></ng-content>` }) export class MyComponent {}
يمكنك بعد ذلك استخدام المكون مع <child-component>Hello from Translusion Component</child-component>
، وسوف نحصل على Yes
HTML التي تم ترميزها بدقة في المكون الفرعي.
بالنسبة إلى التحويل متعدد الفتحات ، يحتوي Angular 2 على محددات يمكنك استخدامها بنفس الطريقة التي @Component
مع تكوينComponent:
<!-- child.component.html --> <h4>Slot 1:</h4> <ng-content select=".class-selector"></ng-content> <h4>Slot 2:</h4> <ng-content select="[attr-selector]"></ng-content>
<!-- parent.component.html --> <child> <span class="class-selector">Hello from Translusion Component</span> <p class="class-selector">Hello from Translusion Component again</p> <span attr-selector>Hello from Translusion Component one more time</span> </child>
يمكنك استخدام select
من العلامات المخصصة الخاصة بك ، ولكن تذكر أن العلامة يجب أن تكون معروفة لـ Angular 2.
فتحات مع Aurelia
أتذكر عندما قلت أن Aurelia تتبع معايير الويب كلما أمكن ذلك؟ في Aurelia ، يُطلق على التحويل اسم الفتحات ، وهو مجرد تعبئة لمكونات الويب Shadow DOM. لم يتم إنشاء Shadow DOM للفتحات بعد ، ولكنه يتبع مواصفات W3C.
<!-- child --> <template> Slot: <slot></slot> </template> <!-- parent --> <template> <child>${textValue}</child> </template>
تم تصميم Aurelia لتكون متوافقة مع المعايير ، ولم يكن Angular 2 كذلك. نتيجة لذلك ، يمكننا القيام بمزيد من الأشياء الرائعة باستخدام فتحات Aurelia ، مثل استخدام المحتوى الاحتياطي (محاولة استخدام محتوى احتياطي في Angular 2 تفشل مع <ng-content> element cannot have content
). انصح:
<!-- child --> <template> Slot A: <slot name="slot-a"></slot> <br /> Slot B: <slot name="slot-b"></slot> Slot C: <slot name="slot-c">Fallback Content</slot> </template> <!-- parent --> <template> <child> <div slot="slot-a">A value</div> <div slot="slot-b">B value</div> </child> </template>
بنفس طريقة Angular 2 ، ستعرض Aurelia جميع تكرارات الفتحة بناءً على تطابق الاسم.
تجدر الإشارة أيضًا إلى أنه في كل من Aurelia و Angular ، يمكنك تجميع أجزاء القالب وعرض المكونات ديناميكيًا (باستخدام <compose>
مع view-model
في Aurelia ، أو ComponentResolver
في Angular 2).
الظل DOM
يدعم كل من Aurelia و Angular Shadow DOM.
في Aurelia ، ما عليك سوى استخدام مصمم الديكور @useShadowDOM
:
import {useShadowDOM} from 'aurelia-framework'; @useShadowDOM() export class YetAnotherCustomElement {}
في Angular ، يمكن فعل الشيء نفسه مع ViewEncapsulation.Native
.
import { Component, ViewEncapsulation } from '@angular/core'; @Component({ //... encapsulation: ViewEncapsulation.Native, }) export class YetAnotherComponent {}
تذكر أن تتحقق مما إذا كان متصفحك يدعم Shadow DOM.
التقديم من جانب الخادم
إنه عام 2017 ، والعرض من جانب الخادم هو أمر عصري للغاية. يمكنك بالفعل تقديم Angular 2 في النهاية الخلفية باستخدام Angular Universal ، وستحصل Aurelia على هذا في عام 2017 كما هو مذكور في قرارات فريقها للعام الجديد. في الواقع ، هناك عرض توضيحي قابل للتشغيل في مستودع Aurelia.
بالإضافة إلى ذلك ، تتمتع Aurelia بقدرات تحسين تقدمية لأكثر من عام ، وهو أمر لا توفره Angular 2 بسبب بناء جملة HTML غير القياسي.
الحجم والأداء وما هو قادم
على الرغم من أنها لا تظهر لنا الصورة الكاملة ، إلا أن معايير DBMonster ، مع التكوينات الافتراضية والتنفيذ المحسن ، ترسم صورة مقارنة جيدة: تظهر Aurelia و Angular نتائج مماثلة لما يقرب من 100 إعادة عرض في الثانية (كما تم اختباره على MacBook Pro) ، بينما أظهر Angular 1 ما يقرب من نصف هذه النتيجة. يتفوق كل من Aurelia و Angular في الأداء على Angular 1 بحوالي خمس مرات ، وكلاهما يتقدم بنسبة 40٪ على React. ليس لدى Aurelia ولا Angular 2 تطبيق DOM افتراضي.
فيما يتعلق بمسألة الحجم ، فإن Angular تبلغ ضعف الدهون مثل Aurelia تقريبًا ، لكن الرجال في Google يعملون على ذلك: تتضمن خريطة طريق Angular إطلاق Angular 4 مع خطط لجعلها أصغر حجمًا وخفيفة الوزن مع تحسين تجربة المطور. لا يوجد Angular 3 ، وفي الحقيقة ، يجب إسقاط رقم الإصدار عند الحديث عن Angular ، حيث يتم التخطيط للإصدارات الرئيسية كل 6 أشهر. إذا نظرت إلى المسار الذي سلكه Angular من ألفا إلى نسخته الحالية ، فسترى أنه لم يكن دائمًا متماسكًا مع أشياء مثل إعادة تسمية السمات من بناء إلى آخر ، وما إلى ذلك. يعد فريق Angular بأن تغيير التغييرات سيكون سهلاً أن تهاجر.
اعتبارًا من عام 2017 ، يخطط فريق Aurelia لإصدار Aurelia UX ، وتوفير المزيد من عمليات التكامل والأدوات ، وتنفيذ العرض من جانب الخادم (الذي كان على خريطة الطريق لفترة طويلة جدًا).
Angular 2 مقابل Aurelia: مسألة ذوق
كل من Angular و Aurelia جيدان ، واختيار أحدهما على الآخر هو مسألة ذوق شخصي وأولويات. إذا كنت بحاجة إلى حل أكثر رشاقة ، فإن Aurelia هو خيارك الأفضل ، ولكن إذا كنت بحاجة إلى دعم المجتمع ، فإن Angular هو الفائز. إنها ليست مسألة "هل يسمح لي إطار العمل هذا ...؟" لأن الإجابة هي ببساطة "نعم". أنها توفر نفس الوظيفة تقريبًا مع اتباع فلسفات وأنماط مختلفة جنبًا إلى جنب مع نهج مختلف تمامًا لمعايير الويب.