اذهب إلى المحتوى

Adnane Kadri

الأعضاء
  • المساهمات

    5129
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    51

كل منشورات العضو Adnane Kadri

  1. طبعا فإن الموضوع يخضع لعدة متغيرات، قد يمكنك إيجاد بعض عروض العمل الخاصة بمشاريع من مثل: مشاريع الاستشارة مشاريع الكتابة التقنية مشاريع التعليم والكورسات وما نحوها من مجالات رغم ندرتها .. أما ان كنت تستهدف المشاريع التنفيذية من مثل العمل أو الإشراف على مشاريع برمجية فقد لا يكون من الكافي تعلم c++ وحدها. ستحتاج في ذلك لغات أخرى يمكن توظيفها في مجالات أخرى. كما أنه قد يمكنك تعلم إطار عمل لها في مجال معين، من مثل crow في مجال الويب، إلا أن هذا يبقى متعلقا بمتطلبات السوق المستهدفة وما ان كان مشارا إليه في عروض المشاريع أو لا. رغم هذا، إلا أنه من النادر وجود مشاريع تتطلبها في مجالات العمل الحر.
  2. مرحبا محمود، انتبه إلى أن المسار التالي: // /api/auth router.get('/', protect, getCurrentUser) محمي بالطبقة الوسيطة protect التي يتم استيرادها من ملف authMiddleware والمعبر عنها بالشيفرة التالية: const jwt = require("jsonwebtoken") const protect = (req, res, next) => { // Get token from header const token = req.header('x-auth-token') // Check if no token if (!token) { return res.status(401).json({msg: 'No token, authorization denied!'}) } // Verify token try { const decoded = jwt.verify(token, process.env.JWT_SECRET) req.user = decoded.user next() } catch (err) { res.status(401).json({msg: 'Token is not valid'}) } } module.exports = protect يتم هاهنا فحص الترويسة x-auth-header من الطلب، والتي تعبر عن رمز توكن الذي يتم به مصادقة الطلب. يتطلب هذا أن يقوم العميل بإرسال قيمة رمز توكن مرتبطة بهاته الترويسة، ولذلك يمكنك استخدام الكود الذي اقترحه المدرب مصطفى لذات الغرض، غير أنك تحتاج هاته المرة وصف ترويسة بذات الاسم:
  3. لا أجد أن الكود الذي لديك به مشكلة ما، يفترض أن يتم طباعة الجمل مرة واحدة ما لم يكن هنالك تأثير من خلال كود آخر. يجب الإشارة أن خطاف useEffect يستقبل كمعامل ثان سلسلة متغيرات يتم تنفيذه كل مرة تتغير قيمة هاته المتغيرات، في مثل الحالة التي هو المعامل والمتغير name، فكل مرة يتم تصيير قيمة جديدة لـ name يتم إعادة تنفيذ الكود والنتيجة: طباعة الجملة مرتين. أما في الحالة الأولى، فالذي يتم تمريره هو سلسلة متغيرات فارغة، بمعنى أنه لن يتم تنفيذ الكود إلا مرة واحدة وهي خلال التصيير الابتدائي initial render. قد لا يمكن تحديد السبب بدقة، ولكن انظر ما ان كنت تقوم بتحديث قيمة name بمكان ما بالشيفرة التي لديك.
  4. ان كنت تقصد الأمر كزائر للموقع فسوف تحتاج في هذا أن يقوم الموقع المستهدف بتزويدك بهاته الميزة - توفر بعض المواقع هاته الخدمة غالبا، أما في حالة تعذر ذلك، فسوف لن يمكن ذلك إلا بتوظيف بعض تقنيات تجريف الويب web scraping لمقاربة نتيجة مماثلة. ولكن ان كنت تقصد أنك مدير الموقع ، فستحتاج في هذا غالبا التعامل مع الاشعارات كانموذج بيانات منفصل تماما، ولذلك فأنك ستحتاج إنشاء جدول للإشعارات يحمل أعمدة من مثل: seen: يعبر عن حالة رؤية أو قراءة الاشعار. content: يعبر عن المحتوى النصي للإشعار. الآن سوف تحتاج إدراج صف إشعار جديد بجدول الإشعارات كل مرة يتم فيها إنشاء منتج جديد. من جهة أخرى، سوف يتم بصفحة مدير الموقع الاستعلام عن كامل الإشعارات غير المقروءة وعرضها. بهذا السناريو البسيط سيمكنك القيام بهاته الجزئية. لا أظن أنه يمكن القيام بذلك بإستخدام جافاسكربت فقط، سوف يتكامل في هذا تطبيق عميل + تطبيق خادم. أي أنك ستحتاج سناريو ويب شامل، وليس على مستوى العميل أو الخادم فقط. أما ان كنت تقصد الإشعار في الوقت الفعلي - أي دون الحاجة إلى تحديث الصفحة أو الدخول إلى صفحة الإشعارات - فأنت غالبا ستحتاج التعامل مع مفهوم الويب السوكيت وبيانات الوقت الفعلي. يمكنك الاستزادة بقراءة الأجوبة على السؤال التالي:
  5. سيمكنك استخدام بعض الأفكار التي تمكنك من فك ترجمة decompile ملف APK ثم ترجمة recompile الناتج مجددا. وأفضل من ذلك بالطبع، يمكنك القيام بتعديلاتك على تطبيق فلاتر بشكل عادي، ثم إعادة بناء نسخة APK من التطبيق. كما أن الأمر قد يخضع لطبيعة التعديلات التي ستقوم بها وحجمها، فإذا كنت تقصد تعديل الشيفرة المصدرية للتطبيق (مثل تغيير الأكواد أو إضافة ميزات جديدة)، فيجب عليك القيام بالتعديلات وإعادة بناء التطبيق ثم استخراج نسخة APK جديدة. أما إذا كنت تقصد تغيير محتوى التطبيق أو النصوص أو الصور دون التدخل في الشيفرة المصدرية، فيمكنك فعل ذلك بسهولة دون الحاجة إلى إعادة بناء التطبيق أو استخراج APK جديدة. ستتغير هذه التغييرات مباشرة على النسخة المثبتة من التطبيق. -رغم أن الفكرة غير منصوح بها وغير عملية، نظرا لأنه سيكون هنالك فارق بين نسخة التطوير ونسخة الإنتاج-.
  6. هل يمكنك مشاركتنا رابط مشروعك على الاستضافة؟ قد يمكن تشخيص المشكلة انطلاقا منها.
  7. سوف تحتاج تهيئة حالة تعبر عما ان كان المستخدم معجبا بالفعل بالمنشور أو لا، ولتسمها مثلا: const (isLiked, setIsLiked) = useState(() => checkLiked()) const checkLiked = () => { /** * أي شيفرة يمكنك انطلاقا منها فحص ما ان كان المستخدم معجبا بالمنشور أو لا */ return someBooleanValue; // أعد true أو false } بحيث تقوم الوظيفة checkLiked بفحص الإعجاب (سواءا بطلبية من الباك أند أو من خلال فحص كائن معين أو أي طريقة كانت). فالقيمة الافتراضية لمتغير الحالة isLiked تتغير هي الأخرى. الآن سيسهل استخدام هذا المتغير في التصيير الشرطي لزر الإعجاب ووظيفته: <ToggleLikeButton onClick={isLiked ? removeLike : addLike} /> const addLike = () => { // وظيفة اضافة الإعجاب } const removeLike = () => { // وظيفة الغاء الإعجاب }
  8. يرجح أن تكون المشكلة متعلقة بإعداد الرابط الجذر Base url لموقعك على الاستضافة، اذ أن livewire تستعمل هذا الإعداد غالبا للتعامل مع طلبيات أجاكس، والتي تستعمل في أحداث مثل wire:click. افتحي console التطبيق بعد استهداف حدث الضغط على الزر مثلا وانظري تفاصيل المشكلة التي تحدث. كحل للمشكلة يقترح اتباع التالي: افتحي ملف env. وقومي بوضع الرابط الجذر لموقعك في APP_URL: APP_URL=https://domain.co/ احفظي الملف، وقومي بتشغيل الأمر php artisan cache:clear لمحو التخزين المؤقت للملفات. في حال ما كان لديك وصول ssh إلى الاستضافة أو إلى تارمنل الاستضافة يمكنك تشغيلها بشكل مباشر عن طريق التصفح إلى مجلد المشروع، أما في حالة التعذر يمكنك استخدام الواجهة Artisan لتشغيل أوامر artisan في داخل التطبيق: نعرف مسارا جديد بملف web.php: use Artisan; .. Route::get('/clear-cache', function(){ Artisan::call('cache:clear'); }); ثم قومي بالتصفح إلى /https://domain.co/clear-cache
  9. كلاهما يعد خيارا ممتاز، وكلاهما يفي بالغرض في الكثير من الحالات ويخدمان الكثير من حالات الاستخدام الشائعة، ولذلك فهما يمكنانك من إنشاء تطبيقات ويب شاملة قوية باستخدام اطار عمل لارافيل. أما عن الفرق بينهما فقد يكون طفيفا في بعض الجزئيات وكبيرا في أخرى، ولكن بشكل عام يمكن مقارنتهما من حيث: السرعة والآداء: قد يلحظ أن هنالك فرقا في الآداء في تطبيق Inertia مقابل تطبيقات Livewire فهي تعمد إلى فصل تطبيقي الخادم والعميل بشكل كامل، وتستخدم مكتبات مثل ReactJS أو أطرا مثل VueJS كإطار عمل للواجهة الأمامية على عكس Livewire التي تستخدم blade كمحرك قالب template engine. ولذلك فإن موضوع السرعة والآداءا غالبا ما يحسم في صف Inertia. سهولة التعلم والتعامل: ممارسة Livewire قد لا تتطلب منك غالبا معرفة مسبقة إلا بلارافيل و PHP، في حين أن Inertia تشترط معرفة مسبقة بإطار عمل VueJS أو ReactJS و لارافيل معا. وهو الأمر الذي يجعل تعلمها يستهلك وقتا أو جهدا أكثر مقارنة بـ Livewire. نفس الشيء بالنسبة للتعامل معها بعد تعلمها، قد تبدوا أكثر تعقيدا في أول الأمر ولكنها ستتضح أكثر مع الوقت. من ناحية الـ SEO: رغم أن Inertia في واحدة من أواخر اصدارتها قد دعمت فكرة التصيير على الخادم Server side rendering، إلا أن هاته النقطة تبقى تحسم لـ Livewire لأنه يتضمنها بالفعل، في حين أن تطبيق Inertia هي تطبيقات صفحة واحدة Single Page Application تتضمن مفهوم التصيير على العميل Client Side Rendering وهو الأمر المعروف تأثيره على الـ SEO. وفي الأخير، تذكر أنك لن تحتاج التخلص من شيء تعلمته حتى تتعلم آخر جديد، يمكنك تعلم الجديد واضافته إلى معارفك ومهاراتك. أين سيمكنك توظيف كل منهما بحسب الحاجة، فهنالك مثلا تطبيقات لا تلتفت كليا لجانب الـ SEO - مثل التطبيقات الإدارية - أين يكون تطبيق الصفحة الواحدة نقطة إيجابية وليست سلبية. على عكس تطبيقات أخرى تعتمد بشكل كليا على فرصها في فهرستها على محركات البحث، هاهنا ستصبح نقطة الصفحة الواحدة نقطة سلبية ولا إيجابية. ولذلك، ان متطلبات مشروعك هي ما تحدد ما الأفضل لك.
  10. لا يظهر أن هنالك أي مشكلة في الكود المرفق، كود جافاسكربت الذي لديك سليم. يرجح أن يكون المتصفح لم يلتقط التحديثات التي قمت بها بعد، قم بإعادة تحديثه وانظر ما ان حلت المشكلة. ان كنت تريد القيام بعمل ترابط متزامن (أي التقاط حي لأي تحديث تقوم به) فأنت ستحتاج غالبا استعمال اضافات vs code، من مثل live server لعمل هاته الوظيفية. لتثبيت هاته الإضافة وتشغيلها اتبع الخطوات التالية: افتح vs code واضغط زر الإعدادات في الجانب الأيسر أسفل الشاشة. اختر extensions من القائمة. ابحث عن live server واختره. سيظهر لك زر تحت أيقونة Live server مكتوب عليه install، اضغطه. انتظر اكتمال التثبيت. أعد تشغيل vs code. افتح vs code على نفس المشروع السابق. اضغط go live في القسم الأيمن أسفل الشاشة. ترقب ظهور التحديثات في المتصفح.
  11. الكود الذي لديك سليم ولا مشكلة به، يجب تعريف كامل خصائص Border مع بعضها لمقاربة مثل هاته النتيجة, وأنت تقوم بذلك. قد تكون المشكلة أنها لا تظهر بسبب أن borderWidth ضئيلة أو بسبب عدم التقاط التحديثات أساسا. جرب تزويد قيمة boorderWith بأكثر وانظر ما ان حلت المشكلة. اجعلها 4 مثلا: borderWidth: 4, أيضا قد يكون هنالك مشكلة بعدم التقاط التحديثات من على Expo go في جهازك. جرب إعادة الإتصال.
  12. وعليكم السلام، قد تحتاجين إعادة النظر في الموضوع قبل حسم قرارك بشكل نهائي، خصوصا وأنه يمكنك طلب توضيح أو شرح إضافي في قسم تعليقات الطلبة وسيهتم المشرفون على الدورات بالتوضيح لك وتوجيهك بشكل أفضل. أيضا سيجب عليك التعامل مع الأمر على أنه شيء طبيعي ان كان في البداية، فذلك أمر عادي يحس به أي طالب جديد متردد على أي مادة علمية جديدة. أما ان كان لا بد، يمكنك التنسيق مع فريق الدعم بخصوص المشكلة أكثر.
  13. القائمة تظهر لدي وبشكل عادي، تأكد فقط من أنك في الصفحة الصحيحة في حسابات حسوب: يمكنك مباشرة التوجه للرابط التالي: https://accounts.hsoub.com/settings/identity كما يمكنك الإطلاع على الفيديو للتفاصيل:
  14. يفضل إرفاق الأكواد بشكل نصي بدل التقاط صور لها، سوف يصعب آنذاك تشخيص المشكلة والعمل عليها. استعمل آداة تحرير الكود في المحرر الخاص بالأكاديمية وقم بلصق شيفرتك هنالك: بالنسبة للمشكلة الأولى التي تواجهها في هذا الكود: numbur = [22 ,33,45,23,1,11,34,88] X_numbur = [] for c in numbur : if numbur > 30 : X_numbur.append(numbur) print(X_numbur) أصلحه ليكون: numbur = [22 ,33,45,23,1,11,34,88] X_numbur = [] for c in numbur : if c > 30 : X_numbur.append(c) print(X_numbur) اذ أن كل عنصر من المصفوفة بحسب حلقة for التي تقوم بها هو c وليس المصفوفة نفسها numbur. أما بالنسبة لهذا الكود: numbur = [22 ,33,45,23,1,11,34,88] X_numbur = [numbur for numbur in numbur if numbur > 30] print(X_numbur) أصلحه ليصبح: numbur = [22 ,33,45,23,1,11,34,88] X_numbur = [n for n in numbur if n > 30] print(X_numbur) لأنك لازلت تقوم بنفس الخطأ، وهو مساواة اسم عنصر المصفوفة في الحلقة باسم المصفوفة نفسها.
  15. بالضبط نعم، غالبا ما يتم الإعتماد على ويب سوكيت لتوفير تجربة حية لعرض البيانات من الخادم في الوقت الفعلي دون الحاجة لإعادة طلب الموارد من الخادم. وفكرتها ببساطة هي: يقوم الخادم ببث قناة معينة، ويقوم بإستهداف حدث معين في حالة تحديث البيانات (مثال: لما نسقتبل اشعارا جديدا). يقوم تطبيق العميل بالإشتراك في قناة معينة، ويقوم بالإستماع لأحداث معينة (مثال: يشترك في قناة المستخدم أحمد ويستمع للحدث "إشعار جديد"). لما يتم استهداف حدث جديد من قبل الخادم يلتقط العميل ذلك، ويتم استلام البيانات التي ارسلها الخادم في حدث معين عبر قناة معينة. يتصرف العميل بناءا على ذلك، مثال: يعطي تنبيها في شكل رسالة نصية. في تجميعة مثل MERN غالبا ما نقوم بالإعتماد على مكتبات مثل socketio للتعامل مع هاته الجزئية. فيما يلي بعض الخطوات العامة للقيام بذلك: تأكد من تثبيت Node.js على جهاز الخادم الخاص بك. قم بإنشاء مجلد جديد لمشروعك وقم بتثبيت مكتبة Socket.io باستخدام npm: npm install socket.io . أنشئ خادما باستخدام Node.js وSocket.io: const http = require('http'); const express = require('express'); const socketIo = require('socket.io'); const app = express(); const server = http.createServer(app); const io = socketIo(server); // قم بإعداد مجلد الويب العام (public) لاحتياجات العميل (الملفات الثابتة مثل CSS و JavaScript). app.use(express.static(__dirname + '/public')); // رسالة ترحيبية عند الاتصال بالخادم. io.on('connection', (socket) => { console.log('عميل متصل'); // إرسال إشعار إلى العميل الجديد عند الاتصال بنجاح. socket.emit('notification', 'مرحبًا بك! أنت متصل الآن.'); // قم بالاستماع إلى أحداث العميل والتفاعل معها. socket.on('disconnect', () => { console.log('عميل غير متصل'); }); }); // تشغيل الخادم على المنفذ 3000. server.listen(3000, () => { console.log('الخادم يعمل على المنفذ 3000'); }); . الآن سنقوم بإنشاء العميل (واجهة المستخدم) باستخدام HTML وJavaScript: <!-- public/index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Socket.io Notifications</title> </head> <body> <h1>Socket.io Notifications</h1> <div id="notification"></div> <!-- تضمين مكتبة Socket.io --> <script src="/socket.io/socket.io.js"></script> <script> // الاتصال بالخادم باستخدام Socket.io const socket = io(); // استماع لإشعارات الخادم socket.on('notification', (message) => { const notificationElement = document.getElementById('notification'); notificationElement.innerHTML = message; }); </script> </body> </html>
  16. ما تحاولين الإشارة إليه هو غالبا سكربت لاختصار الروابط ويكون مشروع ويب متكامل، فيما يلي بعض الخطوات العامة التي يمكنك اتباعها لنمذجة هاته الفكرة: أعد مشروعك وهيئه. قم بإنشاء قاعدة بيانات تحمل الجداول: الجدول الأول هو جدول الروابط والثاني هو جدول المستخدمين والثالث جدول المشرفين. قم بإنشاء صفحات العرض الخاصة بـ: صفحة الأدمن اين يفحص سجلات كل مستخدم وعدد الزيارات على كل رابط يمتلكه - صفحة اعادة التوجيه - صفحة المستخدم التي يقوم فيها بإنشاء روابط مختصرة. قم بإنشاء موجهات تستقبل طلب الرابط المختصر ثم تقوم بتوجيهه نحو الرابط الأصلي بعد تسجيل نقطة أو زيارة للمستخدم. قم ببرمجة عملية تسجيل الدخول بالنسبة لكل من الأدمن والمستخدم وقم بوصف الوظيفية الخاصة بعملية تسجيل الاعلان وتسجيل الزيارة وما الى ذلك. ان شئت استخدام سكربت جاهز فقد تحتاجين الاطلاع على متاجر المتجات الرقمية علك تجدين سكربت مماثل، متجر بيكاليكا للمنتجات الرقمية قد يحمل مثلها مثلا.
  17. الإجابة باختصار هي: لا يمكن، مادام أنه على المتصفح فالعميل يمكنه تحميله والحصول عليه بأي طريقة. ولذلك فإن الطريقة الوحيدة لمنع تحميله والحصول عليه بشكل كامل هي بمنعه من جهة الخادم، وعدم ارساله إلى العميل أساسا. بعض الطرق التي قد تستعمل لهذا الغرض على مستوى العميل هي فقط بغرض تصعيب مهمة التحصل على هاته الملفات على تطبيق العميل، وخصوصا العملاء الغير تقنيين، من مثل: عرض الملف ضمن iframe واضافة طبقة شفافة فوق عنصر iframe لكي يمنع الوصول إلى الملف بشكل مباشر. يمكن وضعها بشكل مطلق absolute هي والـ iframe ضمن حاوية تمتلك الوضعية النسبية relative. منع فتح قائمة السياق context menu للإطلاع على الشيفرة المصدرية للموقع والتحصل على رابط الملف من هنالك. استخدم خوارزمية تشفير معينة لتشفير الملفات المرسلة من الخادم وفك شفرتها على تطبيق العميل، قم بعد ذلك بتشويش شيفرة جافاسكربت الخاصة بك.
  18. وعليكم السلام، في الأساس، المعامل الفارغ الآمن يُستخدم للتحقق من وجود القيم في الكائنات والمصفوفات بشكل آمن دون الحاجة للتحقق يدويًا ودون رمي استثناءات أو اظهار أخطاء في حالة عدم وجود القيم .. الأمر الذي يساعد على جعل الشفرة أكثر إتقانًا وقراءةً وصيانةً. تخيل السيناريو التالي: يوجد لدينا صنف User و Profile بحيث يمتلك الأول خاصية profile، في حين يمتلك الثاني خاصية باسم name class User { public $profile = null; public function __construct($profile = null){ if(!is_null($profile)){ $this->profile = $profile; } } } class Profile { public $name = null; public function __construct($name){ $this->name = $name; } } بحيث لما ننشئ مستخدما جديدا، نحن نتحكم فيما إن كان يمتلك بروفايلا أو لا. هذا البروفايل فيه بياناته الشخصية على سبيل الاسم name وغيرها. في السابق وبدون المعامل الفارغ، كنا نقوم بالمقاربة التالية لاستخراج الخاصية name من خلال user: $profile = new Profile('ahmed'); $user = new User($profile); $name = null; // تصريح قيمة افتراضية لمتغير باسم name if ($user !== null && $user->profile !== null && $user->profile->name !== null) { $name = $user->profile->name; // تخزين الاسم في متغير } echo $name; // إما قيمة الاسم إذا كان موجودًا أو null إذا لم يكن موجودًا. أما الآن فسيكفينا كتابة السياق التالي: $name = $user?->profile?->name; echo $name; بدون المعامل الفارغ سوف تحتاج القيام بالكثير من التحققات، لأنك لو حاولت قراءة name مباشرة من خلال: $name = $user->profile->name; سوف يظهر لك خطأ على نحو: Warning: Attempt to read property "name" on null in /home/user/scripts/code.php on line 23
  19. بإشتراكك في احد الدورات سوف تحصل على وصول للدورة التي اشتركت بها بالإضافة إلى المسار الأول من كل دورة أخرى، مثال: ان قمت بالإشتراك في دورة تطوير واجهات المستخدم فإنك ستحصل بالإضافة إلى هاته الدورة على وصول لكامل المسارات التالية: أساسيات إدارة تطوير المنتجات من دورة إدارة تطوير المنتجات. مدخل إلى علوم الحاسبو من دورة علوم الحاسوب. أساسيات لغة بايثون من دورة تطوير التطبيقات باستخدام لغة باييثون. أساسيات لغة جافاسكربت من دورة تطوير التطبيقات باستخدام لغة جافاسكربت. أساسيات لغة PHP من دورة تطوير التطبيقات باستخدام لغة PHP. أساسيات لغة روبي من دورة تطوير التطبيقات باستخدام لغة Ruby.
  20. وعليكم السلام، Zoho واحدة من الشركات المعروفة بتقديم حلول متكاملة لأعمال الويب، بما في ذلك خدمات استضافة الدومين والبريد الإلكتروني والتسويق عبر البريد الإلكتروني والكثير من التطبيقات الأخرى. بخصوص الإيميل، فهي تقدم خدمات تسمى "Zoho Mail" و "Zoho Campaigns" تتيح لك القيام بذلك. هذه الخدمات لديها واجهات سهلة الاستخدام وتقدم العديد من الميزات المفيدة لأصحاب المواقع. لم أستعمل Zoho لهذا الخصوص، كنت قد استعملتها فيما مضى مع فريق في إدارة أحد المشاريع البرمجية وفي إدارة Scrum sprints وكانت تجربة الإستخدام ممتازة. أرجح أنها مثل ذلك أو أكثر في غيرها من تطبيقاتها.
  21. تذكر أن props ما هو إلا كائن خواص نسنده إلى مكون رياكت، فأي خاص تتعلق بالمكون الأب والأبناء نضعها فيها. من بينها user أو المستخدم الحالي. مثل هاته الأمور التي نتوقع تكرارها في كثير من أجزاء التطبيق، فنقوم بضبطها كخاصية يسهل الوصول إليها في أي جزء من المكونات.
  22. فكرة history.push في رياكت هي ببساطة التوجيه من الصفحة الحالية إلى الصفحة المعطاة بإستخدام react-router، فهي تستقبل كمعامل أول الوجهة المستهدفة. ونستعملها ضمن سياق props وكتابع لها لأنه يتم تصريحها ضمنه -ضمن خواص المكون-، ولذلك فإن history هو كائن يتواجد كخاصية ضمن props في حين أن push هي تابع لهذا الكائن. هاته هي الفكرة ببساطة. props.history.push('/destination-page')
  23. نعم، وهو المشروح بالفعل في التعليق السابق.
  24. يمكنك اضافة القيد ON DELETE عند إنشاء كل سجل لمفتاح أجنبي، يذكر أن هذا القيد يقبل القيم: CASCADE: أين يتم حذف السجل الابن عند حذف السجل الأب. (مثال: عند حذف الفئة يتم حذف المنتجات التي تنتمي لهاته الفئة). RESTRICT : أين يتم منع حذف السجل الأب عندما يمتلك أي سجل ابن. (مثال: لا يمكن حذف الفئة قبل حذف المنتجات التي تنتمي لهاته الفئة). SET NULL: أين يتم استبدال قيمة FK بـ NULL في الابن عند حذف الأب. (مثال: عند حذف الفئة يتم وضع قيمة NULL للمفاتيح الأجنبية في المنتجات التي تنتمي لهاته الفئة) NO ACTION: أين لن يحدث أي شيء، ويتم رد عملية الحذف. SET DEFAULT: أين يتم ضبط سجل أب افتراضي في حالة حذف الأب الأصلي. (مثال: عند حذف الفئة "رياضة" يتم وضع قيمة معرف فئة "عام" للمفاتيح الأجنبية في المنتجات التي كانت تنتمي لهاته الفئة "رياضة") ما تبحث عليه، هو SET NULL أو SET DEFAULT. ففي الأولى نعرف المفاتيح كـ: CONSTRAINT fk_category_product FOREIGN KEY (category_id) REFERENCES categories (id) ON DELETE SET NULL أما في الثانية فنعرفها كـ: category_id INT DEFAULT 1 CONSTRAINT fk_category_product FOREIGN KEY (category_id) REFERENCES categories (id) ON DELETE SET DEFAULT
  25. لا علاقة لذلك، ليس هنالك في ويندوز 11 ما يعيق على البرمجة. وخصوصا في مجال تطوير الويب. فأنت لن تحتاج في الأخير إلا متصفح ويب مثل chrome ومحرر أكواد مثل sublime text أو visual studio code. وهما ما يؤثران غالبا على انتاجيتك أو قدرتك على التطوير أو مصادفتك للمشاكل. طبعا فإن طبيعة هاته المشاكل التي صادفتها هي ما تحدد سببها الأول، حاول البحث عن مدلولها وحلها، يمكنك الاستمرار في استخدام ويندوز 11، سوف لن يكون لذلك أي دخل.
×
×
  • أضف...