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

أحمد حبنكة

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

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

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

إجابات الأسئلة

  1. إجابة أحمد حبنكة سؤال في كيفية استخدام componentDidMount فى الfunctional component بلغة الreact.js كانت الإجابة المقبولة   
    يمكن محاكاة جميع lifecycle methods باستخدام الخطاف useEffect فمثلاً يمكن استبدال الكلاس التالي:
    class A extends React.Component{ constructor(props){ super(props); this.state = { mousePos: {x: 0,y: 0} }; this.handleMouseMove = this.handleMouseMove.bind(this); } handleMouseMove(ev){ this.setState({mousePos: {x: ev.offsetX, y: ev.offsetY}}); } componentDidMount(){ window.addEventListener("mousemove",this.handleMouseMove); } componentWillUnmount(){ window.removeEventListener("mousemove",this.handleMouseMove); } render(){ return <p>Mouse Pos: ({this.state.mousePos.x},{this.state.mousePos.y})</p> } } بالـfunctional Component التالية:
    function A(){ const [mousePos,setMousePos] = useState({x: 0,y: 0}); function handleMouseMove(ev){ setMousePos({x: ev.offsetX,y: ev.offsetY}); } useEffect(() => { window.addEventListener("mousemove",handleMouseMove); return () => { window.removeEventListener("mousemove",handleMouseMove); } },[]); return <p>Mouse Pos: {mousePos.x,mousePos.y}</p>; } لنشرح مثالنا بشكل مبسط، كود componentDidMount صار داخل useEffect وكود componentWillUnmount صار داخل ما يسمى cleanup function وهو تابع نرده من داخل التابع الممرر للـuseEffect.
    ولكن ما هذه المصفوفة التي نمررها في المعامل الثاني؟!!! للحقيقة تابع useEffect أقوى بكثير من توابع lifecycle ولذلك هذه المصفوفة موجودة وبرأيي لتفهم الخطاف useEffect حقاً فكر فيه بالطريقة التالية:
    عند استدعاء الخطاف useEffect اﻻستدعاء التالي:
    useEffect(() => { doSomethingWithAAndB(a,b); return () => { doCleanUpWithAAndB(a,b); }; },[a,b]); فإننا نقول للـReact "كلما تغيرت قيمة a أو قيمة b نفذ التابع doSomethingWithAAndB، أوه ولا تنس تنفيذ التابع doCleanUpWithAAndB قبل ذلك لتنظيف آثار تنفيذ التابع doSomethingWithAAndB بالقيم القديمة"، فلنشرح هذه الجملة ولنفترض القيم البدائية لـa هي 0 وb هي 0 أي هما رقمان وبالنسبة لـ من أين أتى المتحولان a وb ففي غالب اﻷحيان هما معرفان بالشكل اﻵتي:
    const [a,setA] = useState(0); const [b,setB] = useState(0); لكن قد يكونان معرفين على شكل useMemo أو أي شيء آخر، المهم أن هناك طريقة لتغيير قيمة a أو قيمة b تتسبب بعملية rerender للـReact Component.
    اﻵن قيمة a هي 0 وقيمة b هي 0، عند أول render يستدعى الخطاف useEffect حينها التابع doSomethingWithAAndB ينفذ ممرراً له القيمتان 0 و0.
    لنفترض أننا قمنا بعمل setA إلى القيمة 1 بفعل زر ما في الواجهة أو ما شابه، لقد تغيرت قيمة a اﻵن من 0 إلى 1 ولدينا rerender إذاً أولاً ننفذ التابع doCleanUpWithAAndB ممررين له القيمة القديمة لـa أي 0 وقيمة b التي لم تتغير 0، بعد ذلك يستدعى التابع doSomethingWithAAndB بالقيم الجديدة أي نمرر 1 و 0 كمعاملين لهذا التابع.
    عند تغيير قيمة b يحصل نفس الشيء وهكذا، أما عندما يحدث unmount للـReact Component ينفذ التابع doCleanupWithAAndB بالقيم الحالية لـa وb فقط ولا ينفذ doSomethingWithAAndB.
    معقد أليس كذلك؟ نعم أعترف بأن الخطاف useEffect معقد ولكن ما إن تفهم كيف يعمل ستجد بأنه أجمل بكثير من lifecycle methods.
    أخيراً أشجعك على قراءة المزيد عن هذا الخطاف من هذا الرابط: 
    https://wiki.hsoub.com/React/hooks_effect
  2. إجابة أحمد حبنكة سؤال في طريقة تغيير ال boolean داخل object باستخدام redux كانت الإجابة المقبولة   
    الطريقة الوحيدة لعمل ما تريده في حالتك هي نسخ المصفوفة قبل التعديل عليها هكذا:
    const newmyAllAds = [...state.myAllAds]; newmyAllAds[action.payload].isFav = false; return { ...state, myAllAds: newmyAllAds, myFavorite: [...state.myFavorite, action.payload], }; وبهذا يتم التعديل.
    ولكن لماذا لا تتعلم redux-toolkit وحينها بدلاً من كل هذا التعقيد يصير تابع add شبيهاً بالتالي:
    const item = state.myFavorite.find( (item: ItemInter) => item.id === action.payload.id, ); if (item) return; state.myFavorite.push(action.payload); state.myAllAds[action.payload].isFav = false;  
  3. إجابة أحمد حبنكة سؤال في كيف يمكنني ان استعمل اكثر من button لفعل نفس النتيجة بإستخدام دالة onclick() كانت الإجابة المقبولة   
    بما أن عقد i تضاف ديناميكياً فقبل إضافتها أي قبل استدعاء التابع newTask هي غير موجودة ضمن document لذلك التعليمة التالية:
    document.querySelectorAll("i").addEventListener("click",icon) لن تعمل، فلنزلها وننظر أين نقوم بإضافة عقدة i إلى document ؟ هنا:
    //new i in newdiv let newi=document.createElement('i'); newdiv.appendChild(newi); newi.setAttribute("class", "bi bi-x-square-fill"); هنا يمكننا تعريف onclick بإحدى طريقتين إما:
    //new i in newdiv let newi=document.createElement('i'); newdiv.appendChild(newi); newi.setAttribute("class", "bi bi-x-square-fill"); newi.onclick = icon; أو نستخدم addEventListener هكذا:
    //new i in newdiv let newi=document.createElement('i'); newdiv.appendChild(newi); newi.setAttribute("class", "bi bi-x-square-fill"); newi.addEventListener('click',icon); وعلى فكرة يمكن جعل appendChild في النهاية هكذا:
    //new i in newdiv let newi=document.createElement('i'); newi.setAttribute("class", "bi bi-x-square-fill"); newi.addEventListener('click',icon); newdiv.appendChild(newi); فقد جرت العادة أننا نجهز العقدة أولاً ثم نضيفها إلى document.
    المعنى من كل هذا أن ناتج الدالة document.createElement هي عقدة DOM تملك جميع خصائص DOM بما في ذلك onclick حتى ولو لم تضف إلى document بعد أي لم تضف إلى الواجهة التي تظهر للمستخدم.
  4. إجابة أحمد حبنكة سؤال في مشكلة في استخدام الدالة process في node.js كانت الإجابة المقبولة   
    السبب في ذلك أن الحدث exit هو حدث اﻹنهاء العادي أي من دون أخطاء ومن دون event loops ومن دون kill
    من أجل التقاط جميع حالات اﻹغلاق بما فيها Ctrl + C وExceptions وغير ذلك نكتب الكود التالي:
    // attach user callback to the process event emitter // if no callback, it will still exit gracefully on Ctrl-C callback = // some function; // do app specific cleaning before exiting process.on('exit', callback); // catch ctrl+c event and exit normally process.on('SIGINT', function () { console.log('Ctrl-C...'); process.exit(2); }); //catch uncaught exceptions, trace, then exit normally process.on('uncaughtException', function(e) { console.log('Uncaught Exception...'); console.log(e.stack); process.exit(99); }); الكود السابق ينفذ تابع callback عند اﻹغلاق النظامي ويطبع Ctrl-C... ويغلق الـprocess عند الضغط على Ctrl+C وأخيراً في حال حدوث exception يطبع الـstacktrace ويغلق process، طبعاً أنت يمكنك إسناد نفس التابع لجميع اﻷحداث، المهم هو الفكرة.
  5. إجابة أحمد حبنكة سؤال في خطأ Node Sass version في React كانت الإجابة المقبولة   
    node-sass غير منصوح بها بعد اﻵن إذ ينصح فريق مطوري لغة SASS باستخدام ما يسمى بـDart SASS والتي تنصب باﻷمر التالي:
    npm i -D sass نعم أعلم أن documentation لجماعة create-react-app يقولون بأن تنصب node-sass ولكن سبب ذلك أن node-sass لم تصر deprecated إلا منذ عهد حديث(شهر أكتوبر الماضي) وdocumentation الخاص بـcreate-react-app يحتاج إلى تحديث.
  6. إجابة أحمد حبنكة سؤال في ايصال خطاف مصطنع ب redux كانت الإجابة المقبولة   
    تابع connect الخاص بـredux لا يعمل على تغليف خطاف بل على تغليف component مثال:
    import { connect } from 'react-redux'; function Component(props) { const {postForm} = props; // use postForm in some way return (<div>{state}</div>); } const mapDispatchToProps = (dispatch) => { return { postForm: (state) => dispatch(formForm(state)) }; }; export default connect(null, mapDispatchToProps)(Component); ذلك بأن تابع connect يمرر props إلى Component من redux ولا يمررها إلى خطاف.
    إن كنت قد أردت استعمال إحدى props داخل خطاف يمكنك فعل اﻵتي:
    import { useState } from 'react'; import { connect } from 'react-redux'; function useForm() { const [state, setState] = useState(initialState); return [state, setState]; } function Component(props){ const [form,setForm] = useForm(); const {postForm} = props; const submitHandler = () => postForm(form); return (<button onClick={submitHandler}></button>) } const mapDispatchToProps = (dispatch) => { return { postForm: (state) => dispatch(formForm(state)) }; }; export default connect(null, mapDispatchToProps)(Component); أخيراً لدى react-redux الخطافين useSelector وuseDispatch واللذين يغنيانك عن connect هكذا:
    import { useState } from 'react'; import { useDispatch } from 'react-redux'; function useForm() { const [state, setState] = useState(initialState); return [state, setState]; } function Component(){ const [form,setForm] = useForm(); const dispatch = useDispatch(); const submitHandler = () => dispatch(formForm(state)); return (<button onClick={submitHandler}></button>) } export default Component;  
  7. إجابة أحمد حبنكة سؤال في تخزين JWT في localStorage بإستخدام React كانت الإجابة المقبولة   
    بعكس ما يظنه البعض نعم تخزين token في localStorage غير آمن حتى وإن كنت تستخدم ReactJS، إذاً أين أخزنها ﻷن السيرفر يحتاجها؟
    قل لجماعة السيرفر أن يخزنوها بالـCookies وليجعلوها Http-Only أي لا يمكن قراءتها من الجافاسكريبت ولينسوا ذاك Authorization Header ﻷنه يجبر مبرمج frontend على استخدام طرق غير آمنة لتخزين token.
    وﻷن Cookie لا يمكن قراءتها بالجافاسكريبت لذلك خزن في localStorage عند تسجيل الدخول الناجح متحول بولياني وضعه على true، هذا فقط من أجل واجهة المستخدم حتى لا يضطر المستخدم لتسجيل الدخول مع كل request وليس للأمان واﻷمان يتحقق منه السيرفر من خلال التحقق من Cookies المرسلة مع request.
    لا تقلق بشأن الـAJAX requests التي تقوم بها ﻷن Cookies ترسل بشكل تلقائي مع request ولا داعي ﻷن تقوم بذلك بنفسك إلا إذا كنت ترسل cross-domain request حينها كل ما عليك هو تمرير withCredentials: true ضمن request config لمكتبة axios مثال:
    axios.get('https://domaindifferentfromours.com', { withCredentials: true }); بالطبع ما قلته هو الحل المثالي ولكن الواقع قد يفرض عليك تخزين JWT Token ضمن localStorage وهذا هو الحال عند استخدام third-party API مثلاً حيث لا يمكنك التحكم بالسيرفر.
     
  8. إجابة أحمد حبنكة سؤال في استخدام axios لارسال form data كانت الإجابة المقبولة   
    إن مكتبة axios حين تمرر لها body فإنها تفترض أنك تريد أن تعمل POST لـJSON وهذا ما ترسله للمخدم، إذا أردت إرسال multipart/form-data يجب عليك إنشاء FormData object وملؤه بالحقول هكذا:
    // تعريف متغير ليستقبل formData const payload = new FormData(); // إعطائه القيم payload.append('userName', 'usertest'); payload.append('userEmail', 'usertest@gmail.com'); payload.append('file',fileObject) // if you have <input type="file"/> you can get fileObject from inputElement.files[0] if input is not multiple or inputElement.files if it is multiple axios({ method: 'post', url: '/addUser', data: payload }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); لاحظ أننا أزلنا Content-Type header ولا داعي له بل من الخطأ تمريره ﻷن axios عند تمرير FormData فإنها تفهم أن Content-Type يجب أن يكون multipart.
    طبعاً أنت تعلم أن multipart يستخدم فقط إن كان هناك file upload أما إذا كانت جميع حقولك عادية حينها لا نمرر FormData object بل نمرر URLSearchParams object بالشكل التالي:
    axios({ method: 'post', url: '/addUser', data: new URLSearchParams(body) // body is a regular javascript object }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); حينها تمرر axios الـContent-Type header بقيمة application/x-www-form-urlencoded 
    أخيراً إن كنت تريد تمرير JSON للسيرفر حينها تقوم باﻵتي:
    axios({ method: 'post', url: '/addUser', data: body // body is a regular javascript object }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); حينها يكون Content-Type يساوي application/json
  9. إجابة أحمد حبنكة سؤال في كيفية تشغيل الشيفرة باستخدام React useEffect مرة واحدة فقط كانت الإجابة المقبولة   
    إن useEffect تدمج الـlifecycle methods الثلاثة في تابع واحد، useEffect تستعمل حين تريد تنفيذ كود معين عند كل تغير لمتحولات معينة، فمثلاً الكود التالي:
    useEffect(() => { console.log(name); },[name]) سيطبع name كلما تغير، قد يكون name هذا prop من أب وقد يكون state ، لا يهم كيف يتغير كل ما يهم أنه كلما تغير سنقوم بطباعته، طبعاً الكود بداخل useEffect ينفذ مرة واحدة على اﻷقل ولذا يمكن استعماله بديلاً عن componentDidMount هكذا:
    useEffect(() => { // do something },[]); لاحظ المصفوفة الفارغة، تلك طريقة نخبر فيها useEffect أن الكود لا يعتمد على أية متحولات لذا ينفذ مرة واحدة عند كل mount للـcomponent.
    طبعاً يمكننا تمرير عدة متحولات داخل المصفوفة مثل اﻵتي:
    useEffect(() => { console.log(a+b); },[a,b]); الكود السابق يطبع مجموع a وb كلما تغير a أو تغير b.أخيراً يمكن للتابع الممرر كـcallback للـuseEffect أن يرد ما يسمى cleanup function ، كما في المثال التالي:
    useEffect(() => { if(name === 'ahmad'){ window.addEventListener('mousemove',mousemovelistener); return () => { window.removeEventListener('mousemove',mousemovelistener); } } },[name]); الكود السابق يفحص name إن كان يساوي ahmad يضيف listener للحدث mousemove ، عندما يتغير name إلى قيمة مثل "a" نريد للـmousemovelistener أن يزال لذلك كتبنا الكود التالي:
    return () => { window.removeEventListener('mousemove',mousemovelistener); } عندما ترد تابعاً هكذا يفهم useEffect أن عليه تنفيذ هذا التابع أولاً ثم نغير dependency (والتي في المثال السابق هي name) ثم ننفذ الكود داخل useEffect من جديد.
    أعتقد أنك قد لاحظت أن useEffect أفضل وأقوى من lifecycle methods ، ليس ذلك فقط بل يمكنك كتابة عدة useEffect في component هكذا:
    useEffect(() => { console.log(name); },[name]); useEffect(() => { console.log(a+b); },[a,b]); كل effect في المثال السابق مستقل تماماً عن غيره، أليس هذا رائعاً؟!!!
  10. إجابة أحمد حبنكة سؤال في استخدام lifecycles في react useeffect كانت الإجابة المقبولة   
    إن useEffect تدمج الـlifecycle methods الثلاثة في تابع واحد، useEffect تستعمل حين تريد تنفيذ كود معين عند كل تغير لمتحولات معينة، فمثلاً الكود التالي:
    useEffect(() => { console.log(name); },[name]) سيطبع name كلما تغير، قد يكون name هذا prop من أب وقد يكون state ، لا يهم كيف يتغير كل ما يهم أنه كلما تغير سنقوم بطباعته، طبعاً الكود بداخل useEffect ينفذ مرة واحدة على اﻷقل ولذا يمكن استعماله بديلاً عن componentDidMount هكذا:
    useEffect(() => { // do something },[]); لاحظ المصفوفة الفارغة، تلك طريقة نخبر فيها useEffect أن الكود لا يعتمد على أية متحولات لذا ينفذ مرة واحدة عند كل mount للـcomponent.
    طبعاً يمكننا تمرير عدة متحولات داخل المصفوفة مثل اﻵتي:
    useEffect(() => { console.log(a+b); },[a,b]); الكود السابق يطبع مجموع a وb كلما تغير a أو تغير b.
    أخيراً يمكن للتابع الممرر كـcallback للـuseEffect أن يرد ما يسمى cleanup function ، كما في المثال التالي:
    useEffect(() => { if(name === 'ahmad'){ window.addEventListener('mousemove',mousemovelistener); return () => { window.removeEventListener('mousemove',mousemovelistener); } } },[name]); الكود السابق يفحص name إن كان يساوي أحمد يضيف listener للحدث mousemove ، عندما يتغير name إلى قيمة مثل "a" نريد للـmousemovelistener أن يزال لذلك كتبنا الكود التالي:
    return () => { window.removeEventListener('mousemove',mousemovelistener); } عندما ترد تابعاً هكذا يفهم useEffect أن عليه تنفيذ هذا التابع أولاً ثم نغير dependency (والتي في المثال السابق هي name) ثم ننفذ الكود داخل useEffect من جديد.
    أعتقد أنك قد لاحظت أن useEffect أفضل وأقوى من lifecycle methods ، ليس ذلك فقط بل يمكنك كتابة عدة useEffect في component هكذا:
    useEffect(() => { console.log(name); },[name]); useEffect(() => { console.log(a+b); },[a,b]); كل effect في المثال السابق مستقل تماماً عن غيره، أليس هذا رائعاً أم ماذا؟!!!
  11. إجابة أحمد حبنكة سؤال في كيف أضيف عنصرًا إلى قائمة في redux reducer؟ كانت الإجابة المقبولة   
    بما أن توابع redux يجب أن تكون pure أي لا يجوز التعديل على state object يدوياً بل إرجاع object جديد مختلف عن السابق إن أردنا التعديل، وفق هذا المبدأ فإن هذا السطر:
    arr: state.arr.push([action.newItem]) خاطئ ﻷنه يعدل على المصفوفة بشكل مباشر، الحل هو التالي:
    arr: [...state.arr,action.newItem] السطر السابق يستعمل ميزة array rest حيث تنتج مصفوفة جديدة فيها كل عناصر state.arr ومضافاً إليها action.newItem، يمكن استخدام ميزة array rest لدمج مصفوفتين أيضاً بالشكل اﻵتي:
    arr: [...state.arr,...action.newItems] ويمكن إضافة عنصر في بداية المصفوفة بدلاً من نهايتها هكذا:
    arr: [action.newItem,...state.arr] بالمناسبة أنا أنصحك أن تتعلم redux-toolkit وتستخدمها في جميع مشاريع redux وهذا ما ينصح به فريق مطوري redux، لماذا؟ ﻷن مثالك بعد redux-toolkit يمكن استبداله بالكود التالي:
    import {createSlice} from "@reduxjs/toolkit"; const slice = createSlice({ name: "items", initialState: [], reducers: { addItem(state,action){ state.arr.push(action.payload); } } }); const {actions,reducer} = slice; const {addItem} = actions; export default reducer; export addItem; // addItem is an action creator so we dispatch it like this dispatch(addItem(newItem)); لاحظ أننا استعملنا state.arr.push وهذا صحيح ﻷن redux-toolkit تستعمل مكتبة اسمها immer التي تعمل بالطريقة التالية: الـstate الممرر في addItem method هو draft State object مختلف عن state object المخزن داخل redux ، كل تعديل على هذا draft object تلتقطه مكتبة immer المستعملة من قبل redux-toolkit، عند اﻻنتهاء من التعديلات ترجع مكتبة immer كائن object جديد مختلف عن state object القديم وفيه التعديلات المطلوبة.
    يمكنك قراءة المزيد عن redux-toolkit هنا
    ويمكنك قراءة المزيد عن مكتبة immer وفهمها أكثر هنا
  12. إجابة أحمد حبنكة سؤال في هل يمكننا الاستغناء عن ال connect function وتعويضها ب useSelector hook فى الريدكس كانت الإجابة المقبولة   
    وعليكم السلام ورحمة الله وبركاته
    أولاً نعم يمكن استبدال connect بـuseSelector، كلاهما طريقتان لجلب state من redux إلى component الحالية. من ناحية الوظيفة لا يوجد فرق بينهما.
    الفرق الوحيد هو أن useSelector تستخدم React Hooks وهي طريقة جديدة لتعريف state ضمن function components أما connect فيستعمل ما يسمى HoC أي Higher Order Component وهي حين يكون لدينا تابع يأخذ component class or function كمعامل ويرد component class آخر.
    إذاً ماذا نستخدم طالما أنهما يؤديان نفس الوظيفة؟
    اﻷمر يعتمد على ذوقك، شخصياً أجد useSelector أجمل وأسهل للفهم وتوفر علي بعض boilerplate، ربما يجد آخرون connect أفضل أو ﻷنهم اعتادوا عليها.
    أما بالنسبة لما هو شائع فاستخدام Hooks أصبح شائعاً جداً هذه اﻷيام وبالغالب useSelector معه إلا في التطبيقات التي ما زالت تعمل بنسخة React أقل من 16.8 والله أعلم.
    بالتوفيق وشكراً لك
  13. إجابة أحمد حبنكة سؤال في ما هو swagger API .. وماذا يفعل ؟ وهل هى للباك اند ام فرونت اند ؟ كانت الإجابة المقبولة   
    نفترض لدينا backend API فيه endpoints معينة GET,POST,PUT,DELETE وإلخ.
    اﻵن مطورو تطبيق الجوال الذين سيستخدمون هذا API طلبوا منك أنت مبرمج backend توثيق documentation بطريقة جذابة أي يريدون واجهة وب تظهر لهم كل API Endpoints ، ماذا تفعل كل Endpoint ، ما هي معاملاتها وما هو شكل الـresponse وإلخ وليس ذلك فقط.
    يريدون أيضاً من هذه الواجهة تجريب API واللعب به، كيف تقوم أنت بكل هذا ؟
    من خلال كتابة ملف يسمى OpenAPI Specification يوصف API الخاص بك بطريقة معينة ومن ثم يمكنك توليد واجهة documentation من هذا الملف، هذا هو عمل swagger API ، إنه طريقة لبناء واجهة documentation جذابة.
    إن swagger API هي تقنية backend أما طريقة كتابة الملف فيمكنك التعرف عليها من الرابط التالي:
    https://swagger.io/docs/specification/about/
    بعض backend frameworks تدعم swagger API بإحدى طريقتين: إما توليد routes من ملف openapi أو توليد ملف openapi من routes المعرفة والتي يضاف عليها annotation معينة.
    أنا أنصح ﻷي backend API أن يكون موثقاً بالـOpenAPI لما فيه من مرونة ولجمال واجهة documentation التي يولدها.
  14. إجابة أحمد حبنكة سؤال في كيف اعمل post ل API بواسطة ملف josn عن طريق postman ؟؟ كانت الإجابة المقبولة   
    لرفع بيانات json كـbody عليك استعمال ما يسمى بالـraw body كما في الصورة:

    لاحظ أننا اخترنا JSON من القائمة اليمنى حتى يعلم POSTMAN أننا نريد رفع بيانات JSON.
    طبعاً في حالتك عليك فتح ملف الـjson، نسخ محتواه ولصقه ضمن body.
    من طرف المخدم ستجد بيانات الـjson كـrequest body الذي عليك أن تقوم بعمل json decode له حتى تصل للبيانات وطريقة ذلك تعتمد على لغة البرمجة المستخدمة لكن في php يمكن اتباع الكود التالي:
    $json_body_object = json_decode(file_get_contents("php://input"), true) بالتوفيق وشكراً لك
  15. إجابة أحمد حبنكة سؤال في ما معنى run this project locally ؟؟ كانت الإجابة المقبولة   
    أعتقد أنه يقصد أن تقوم بتحميل المشروع من bitbucket وتشغله على جهازك قبل أن تحوله إلى apk.
  16. إجابة أحمد حبنكة سؤال في اخفاء الفيديو بعد انتهائه كانت الإجابة المقبولة   
    الحل يعتمد على استخدام onended event وهو الحدث الذي ينفذ عندما ينتهي الفيديو، نفترض مثلاً أن تضم الفيديو هكذا:
    <video id="myvideo" src="path/to/video" onended="myFunction()"></video> عندها لإخفاء الفيديو نعرف myFunction هكذا:
    function myFunction(){ const videoElement = document.getElementById("myVideo"); videoElement.style.display = 'none'; } وبهذه الطريقة سيختفي الفيديو عندما ينتهي.
     
    لاحظ أننا نخفي الفيديو كما نخفي أي عنصر html عادي وهناك طرق أخرى ﻹخفاء عناصر html ولكن display: none هو ما نريده في معظم اﻷحيان وهو أسرع وأسهل من حذف العنصر من شجرة html.
  17. إجابة أحمد حبنكة سؤال في انشاء كلاس في الجافا كانت الإجابة المقبولة   
    أولاً الكلاس:
    public enum Color{ RED, WHITE, BLUE } public class Car { private int speed; private String model; private Color color; public int getSpeed(){ return speed; } public void setSpeed(int speed){ this.speed = speed; } public String getModel(){ return model; } public void setModel(String model){ this.model = model; } public Color getColor(){ return color; } public void setColor(Color color){ this.color = color; } } لاحظ أننا استخدمنا enum للون وذلك ﻷن ألوان السيارات تكون إحدى قيم محدودة، كل خاصية للكلاس عبارة عن private field مع getter/setter وهذا عرف منصوح به في الجافا.
     
    اﻵن لإنشاء array من الكلاس أعلاه:
    Car[] cars = new Car[2]; cars[0] = new Car(); cars[0].setColor(Color.RED); cars[0].setModel("Mercedes"); cars[0].setSpeed(240); cars[1] = new Car(); cars[1].setColor(Color.BLUE); cars[1].setModel("BMW"); cars[1].setSpeed(260); طبعاً يمكنك إنشاء مصفوفة بأي حجم تريد، لاحظ أن بناء مصفوفة من Car يتمضن خطوتين: أولاً إنشاء المصفوفة، بعد هذه الخطوة يتشكل لدينا مصفوفة بحجم معين كل قيمها عبارة عن null أي أننا لم ننشئ بعد أي Car object.
     
    الخطوة الثانية تكون ملء المصفوفة بـCar objects، طبعاً يمكننا ترك بعض قيم المصفوفة null إن شئنا ذلك وهذا يتبع لمنطق البرنامج الذي نريده.
  18. إجابة أحمد حبنكة سؤال في JavaScript Array كانت الإجابة المقبولة   
    أولاً التعليمة فيها خطأ إذ يجب أن تكون:
    orderRange = Array.from(Array(blocks.length).keys()) وذلك ﻷن keys تابع وليس property.
    واﻵن لنشرح تابع keys هذا بمثال، ضع هذه التعليمة في browser console :
    const a = [1,2,3].keys() اﻵن ضع a ليطبع لك المتصفح قيمته، سيطبع لك المتصفح :
    Array Iterator {} 
    ما هذا ؟ iterator هو ميزة جديدة في ES6 وهو عبارة عن object له method اسمه next باستدعاء هذا الـmethod تتولد قيمة جديدة حسب تعريف iterator ومعها متحول بولياني done والذي يخبرك هل هناك قيم جديدة يمكن توليدها أم لم يعد هناك.
     
    دعنا نوضح هذا الـnext في مثالنا، نفذ التعليمة التالية:
    a.next() سيطبع لك المتصفح:
    {value: 0, done: false} نفذها مرةً أخرى وسيطبع لك:
    {value: 1, done: false} ومرةً أخرى:
    {value: 2, done: false} ومرة أخيرة:
    {value: undefined, done: true} لاحظ أن done صارت true مما يعني أنه لا توجد أي قيم جديدة، لاحظ أن القيم هي 0,1,2 وهي عبارة عن القيم من 0 إلى طول المصفوفة - 1.
     
    وأيضاً كان يمكننا بدلاً من استدعاء next عدة مرات أن نستخدم for-of، نفذ تعليمة for هذه لتعلم ما أقصد:
    for(const k of [1,2,3].keys()){ console.log(k); } أما تابع Array.from فهو يحول أي iterator object إلى مصفوفة.
     
    تعليمتك بالنتيجة ما هي إلى إنشاء مصفوفة قيمها من 0 إلى blocks.length - 1 فقط لا غير.
     
    بالطبع iterator object ليس بالضرورة يولد قيماً من 0 إلى طول مصفوفة ما بل يمكنه توليد أي قيم ﻷي عدد من المرات وبعض iterator object تكون حتى لا نهائية أي done دائماً false ، ما يحدد ماذا يولد iterator object هو التابع الذي تستدعيه، في مثالك array.keys() يولد قيم من 0 إلى طول المصفوفة -1 أما في المثال التالي:
    const s = new Set([1,5,3]).keys() فالـiterator object سيولد 1,5,3.
  19. إجابة أحمد حبنكة سؤال في إنشاء قاعدة بيانات و جدول و إضافة بيانات SQL كانت الإجابة المقبولة   
    السؤال عبارة عن ثلاث خطوات، الخطوة اﻷولى إنشاء قاعدة البيانات والتعليمة هي 
    CREATE DATABASE UNIVERSITY الخطوة الثانية عبارة عن تعليمة CREATE TABLE أعمدته موضحة في السؤال، لدينا أعمدة عادية مثل Student_Name وعمودان عليهما constraint اﻷول عمود Student_Id وهو primary key واﻵخر عمود Department_No وهو Foreign Key.
     
    لمعرفة كيفية كتابة تعليمة إنشاء جدول أنظري للرابط: https://www.w3schools.com/sql/sql_create_table.asp
     
    لمعرفة كيفية تحديد عمود Primary Key انظري الرابط :
    https://www.w3schools.com/sql/sql_primarykey.ASP
     
    لمعرفة كيفية إنشاء عمود Foreign Key انظري الرابط: 
    https://www.w3schools.com/sql/sql_foreignkey.asp
    ملاحظة: يبدو أن عمود Birth_Date هو في الحقيقة unix timestamp عن تاريخ الولادة، يمكنك تحويل أي تاريخ ووقت إلى unix timestamp من الموقع التالي: https://www.unixtimestamp.com/index.php
    باستخدام الروابط السابقة تكون التعليمة المطلوبة:
    CREATE TABLE STUDENT (Student_Name varchar(50), Student_ID int(10) NOT NULL, Birth_Date int(10), Address varchar(50), Department_No int(5), PRIMARY KEY (Student_ID), FOREIGN KEY (Department_No) REFERENCES Department(department_id) ); التعليمة السابقة ستعمل فقط على mysql، إن كنت تستعملين SQL Server فالتعليمة هي:
    CREATE TABLE STUDENT (Student_Name varchar(50), Student_ID int(10) NOT NULL PRIMARY KEY, Birth_Date int(10), Address varchar(50), Department_No int(5) FOREIGN KEY REFERENCES Department(department_id) ); ربما لاحظت أننا وضعنا NOT NULL على Student_ID وذلك لأن المفتاح الرئيسي لا يجوز أن يكون null.
    الخطوة الثالثة هي تعليمة INSERT على الجدول المنشأ مثلاً:
    INSERT INTO Student(Student_Id,Student_Name,Birth_Date,Address,Department_No) VALUES (1,'ahmad',733795200,'',1) حيث ننتبه في المثال السابق على ضرورة وجود Department بالرقم 1 في جدول department.
    بالمناسبة هناك عدة قواعد بيانات تقبل إضافة عدة أسطر(طلاب) في تعليمة واحدة هكذا:
    INSERT INTO Student(Student_Id,Student_Name,Birth_Date,Address,Department_No) VALUES (1,'ahmad',733795200,'',1), (2,'batool',736387200,'',1)  
  20. إجابة أحمد حبنكة سؤال في عداد التكرار لا يعمل جافاسكريبت كانت الإجابة المقبولة   
    يمكنك أخي عماد أن تعرف السبب من الكود التالي:
    (function mainFunc(){ var i,c; function changeColor(color) { color= ["red","blue","black","yellow","white"]; for(i = 0 ; i<color.length ; i=i+1) c=color[i] ; } console.log(c); } return changeColor(); }()); هذا الكود سيطبع "white" فقط وذلك ﻷن قيمة c بعد أن تنتهي حلقة التكرار تساوي "white" وفي الكود الخاص بك ما هو داخل العنصر main سيكون "white".

    ولكن ماذا نفعل لطباعة جميع قيم المصفوفة ؟ المشكلة تكمن في أنك تريد طباعتها داخل عنصر HTML ، إذا أخبرتني بهدفك من ذلك قد نتوصل إلى حل وإلا عليك أن تجد طريقةً أخرى للطباعة.
    لست متأكداً تماماً مما تريد ولكن لعلك تحصل على ما تريد إن استبدلت هذه التعليمة:
    myMain.innerHTML=color[i] ; بهذه:
    myMain.innerHTML+=color[i] + " " ; // المسافة هي لفصل اﻷلوان المراد طباعتها، يمكنك اختيار ما تشاء للفصل بينها مثلاً <br />  
×
×
  • أضف...