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

بلال زيادة

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

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

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

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

    30

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

  1. إجابة بلال زيادة سؤال في ربط جدولين في قاعدة البيانات في PHP كانت الإجابة المقبولة   
    سوف نقوم باستخدام inner join للربط بين الجدولين فيمكنك استخدام inner join بهذا الشكل 
    "SELECT c.*, u.* FROM `chat` as c inner join users as u WHERE u.id = c.sender_id ORDER BY `id` DESC LIMIT 50"; ففي حالة الكود الخاص بك يتم تنفيذ هذا الاستعلام 
    $stmt = $db->prepare("SELECT c.*, u.* FROM `chat` as c inner join users as u WHERE u.id = c.sender_id ORDER BY `ID` DESC LIMIT 50"); ومن ثم يمكنك الوصول إلى جميع الحقول بداخل الجدولين أو يمكنك تحديد مثلاً جميع حقول جدول ما و حقل من الجدول الثاني بهذا الشكل  
    $stmt = $db->prepare("SELECT c.*, u.name FROM `chat` as c inner join users as u WHERE u.id = c.sender_id ORDER BY `ID` DESC LIMIT 50");  
  2. إجابة بلال زيادة سؤال في تغيير اسم الملف قبل الرفع والإرسال للقاعدة في php كانت الإجابة المقبولة   
    يمكنك جلب امتداد الملف عن طريق تقسيم اسم الملف بهذا الشكل 
    $name = explode('.', $_FILES["file"]["name"]); ثم يمكنك برمجة كود ما ليقوم بوضع اسم بشكل عشوائي ويمكن استخدام الكود الذي أرفقته أنت بهذا الشكل 
    $fileName = substr(md5(uniqid(rand(), true)),3,10); ثم يمكنك استخدام دالة end لجلب أخر عنصر في المصفوفة بهذا الشكل 
    $end = end($name); ثم يمكنك دمج المتغيرات ببعضها بهذا الشكل 
    $name = explode('.', $_FILES["file"]["name"]); $fileName = substr(md5(uniqid(rand(), true)),3,10); $end = end($name); $newName = $fileName . '.' . $end; ثم في دالة move_uploaded_file يمكنك وضع الاسم الجديد 
    move_uploaded_file($_FILES["file"]["tmp_name"], $newName);  
  3. إجابة بلال زيادة سؤال في استخدام TabBar لعرض التصنيفات مع عرض منتجات التصنيف المختار في باقي الواجهة في فلاتر كانت الإجابة المقبولة   
    هناك طريقة وهي استخدام StreamController بحيث هي طريقة من طرق إدارة الحالة في فلاتر. و الأمر معقد جداً و يجب أن تكون على دراية جيدة بكيفية استخدام StreamController. لاحظ بأنه يجب أن تقوم بتعلم StreamController حتى تفهم الإجابة جيداً لأنه في الوهلة الأولى ستجد أن الأمر قد يكون فيه صعوبة 
    يمكنك إنشاء ملف وليكن مسؤول عن التنصت على أي حدث جديد و يعكسه على الواجهة أي يقوم بتنفيذ هذا الحدث على الواجهة و الميزة في ذلك إنها تقوم بتنفيذ الحدث بدون اللجوء إلى بناء نفسها من الصفر و هذا الملف فليكن اسمه StreamProductsBloc.dart ويمكننا تعريف عدة متغيرات في هذا الملف بهذا الشكل 
    List<ProductsModel>? products; final StreamController<List<ProductsModel>> _productsController = StreamController<List<ProductsModel>>.broadcast(); final StreamController<int> _categoryController = StreamController<int>.broadcast(); Stream<List<ProductsModel>> get productsStream => _productsController.stream; StreamSink<int> get fetchProducts => _categoryController.sink; Stream<int> get getProductsForCategoriescategory => _categoryController.stream; APIService? apiService; int categoryID = 0; List<ProductsModel>? products; بحيث أول شيء نقوم بتعريف الكلاس مودل الخاص بالمنتجات.
    final StreamController<List<ProductsModel>> _productsController = StreamController<List<ProductsModel>>.broadcast(); و من ثم نقوم بتعريف StreamController ليقوم بالتحكم في العملية , ويتم توفير واجهات مختلفة لإنشاء تدفقات أحداث متنوعة.
    final StreamController<int> _categoryController = StreamController<int>.broadcast(); وحدة تحكم حيث يمكن الاستماع إليه أكثر من مرة .
    Stream<List<ProductsModel>> get productsStream => _productsController.stream; ثم نقوم بالحصول على البث للمراقبة.
    StreamSink<int> get fetchProducts => _categoryController.sink; ثم نقوم بإدخال حدث إضافي عن طريق StreamSink. 
    StreamProductsBloc() { //this.categoryID = categoryID; this.products = []; apiService = APIService(); _productsController.add(products!); _categoryController.add(this.categoryID); _categoryController.stream.listen(_fetchCategoriesFromApi); } Future<void> _fetchCategoriesFromApi(int category) async { this.products = await apiService!.getProductsForCategories(category); _productsController.add(this.products!); } @override void dispose(){ _productsController.close(); _categoryController.close(); } نقوم بإنشاء دالة جلب بيانات التصنيف عند تمرير id التصنيف و نقوم بإرجاع جميع المنتجات و من ثم نقوم بإضافة هذه البيانات إلى وحدة التحكم.
    Future<void> _fetchCategoriesFromApi(int category) async { this.products = await apiService!.getProductsForCategories(category); _productsController.add(this.products!); }  ثم نقوم بإضافة المنتجات و id التصنيف إلى وحدة التحكم في دالة StreamProductsBloc ثم نقوم بمراقبة الحدث عن طريق استخدام listen 
    StreamProductsBloc() { //this.categoryID = categoryID; this.products = []; apiService = APIService(); _productsController.add(products!); _categoryController.add(this.categoryID); _categoryController.stream.listen(_fetchCategoriesFromApi); } ثم نقوم بإنشاء ملف واجهة عرض البيانات وليكن مثلاً باسم products_screen.dart و نقوم أولاً بإنشاء نسخة جديدة من الملف الذي قمنا بإنشائه مسبقاً 
    StreamProductsBloc streamProductsBloc = StreamProductsBloc(); ثم ننشأ عدة متغيرات و نعرف TabController لوضع التصنيفات في هذه TabController
    bool get wantKeepAlive => true; HelperApi helperApi = new HelperApi(); int currentIndex = 0; late TabController _tabController; ثم نقوم بصنع Widget خاصة بعرض التصنيفات في TabController 
    Widget _categories(List<CategoryModel> categoryModel, BuildContext context) { _tabController = TabController( initialIndex: 0, length: categoryModel.length, vsync: this, ); return Scaffold( appBar: AppBar( title: Text(S.of(context).products), bottom: TabBar( indicatorColor: Color(0XFF117182), indicatorWeight: 5, controller: _tabController, tabs: _tabs(categoryModel), isScrollable: true, onTap: (int index) { streamProductsBloc.fetchProducts .add(this.productsCategories[index].id!); }, ), ), body: Container( child: StreamBuilder( stream: streamProductsBloc.productsStream, builder: (context, AsyncSnapshot<List<ProductsModel>>? snapshot) { switch (snapshot!.connectionState) { case ConnectionState.none: // ignore: todo // TODO: Handle this case. return Center( child: CircularProgressIndicator(), ); case ConnectionState.waiting: // ignore: todo // TODO: Handle this case. return ShimmerGrid(); case ConnectionState.done: case ConnectionState.active: // ignore: todo // TODO: Handle this case. if (snapshot.hasError) { return Center( child: ShimmerGrid(), ); } else { if (!snapshot.hasData) { return ShimmerGrid(); } else { return _drawProducts(snapshot.data!, context); } } } }, ), ), ); } لاحظ أننا نقوم بجلب منتجات كل تصنيف عند الضغط عليها عن طريق استخدام id هذا التصنيف 
    streamProductsBloc.fetchProducts.add(this.productsCategories[index].id!); و من ثم نقوم بإضافة هذا الحدث إلى streamProductBloc . 
    ثم نقوم برسم Widget الخاص بالمنتجات 
    Widget _drawProducts(List<ProductsModel> products, BuildContext context) { final cart = Provider.of<Cart>(context, listen: false); var initModel = Provider.of<InitModel>(context, listen: false,); var auth = Provider.of<AuthProvider>(context, listen: false); return Consumer<WishListProvider>( builder: (BuildContext context, wishListData, child) { return Container( padding: EdgeInsets.only(top: 24), child: Column( children: [ Flexible( child: GridView.builder( gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( maxCrossAxisExtent: 200, childAspectRatio: 1 / 2, crossAxisSpacing: 20, mainAxisSpacing: 20), itemCount: products.length, itemBuilder: (context, index) { return Card( clipBehavior: Clip.hardEdge, elevation: 0.9, child: AnimationConfiguration.staggeredList( position: index, duration: const Duration(milliseconds: 375), child: SlideAnimation( verticalOffset: 50.0, child: FadeInAnimation( child: Padding( padding: const EdgeInsets.all(8.0), child: InkWell( onTap: () { _gotoSingleProduct(products[index], context); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Expanded( // ignore: unnecessary_null_comparison child: Stack( children: [ (products[index].images![0].src != null) ? Image.network( products[index].images![0].src!, width: MediaQuery .of(context) .size .width, height: MediaQuery .of(context) .size .height, fit: BoxFit.cover, ) : Image.asset( "assets/images/1.jpeg", width: MediaQuery .of(context) .size .width, height: MediaQuery .of(context) .size .height, fit: BoxFit.fill, ), Positioned.directional( textDirection: Directionality.of( context), child: Container( margin: EdgeInsets.symmetric( horizontal: 12.0, vertical: 10.0), decoration: BoxDecoration( color: Colors.grey[200], borderRadius: BorderRadius.circular(50.0)), child: IconButton( icon: Icon( Icons.favorite_outline), onPressed: () { //wishListData.getCount(products[index].id!, auth.id!); wishListData.addNewWishList( price: products[index] .price! .toString(), product: products[index] .name!, image: products[index] .images![0] .src!, productId: products[index] .id, userId: auth.id); ScaffoldMessenger.of(context) .showSnackBar( SnackBar( content: Text( S .of(context) .add_product_to_wishlist, ), duration: Duration( seconds: 2), ), ); }, iconSize: 20.0, ), ), ) ], ) ), Padding( padding: const EdgeInsets.all(8.0), child: Text( products[index].name!.substring(0, 10), style: TextStyle( color: Colors.black, fontWeight: FontWeight.bold, fontSize: 18.0, ), ), ), Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Padding( padding: const EdgeInsets.all(8.0), child: Text(initModel.currency! + products[index].price!, style: TextStyle( color: Colors.black, fontSize: 15.0, ), ), ), IconButton( icon: Icon( Icons.add_shopping_cart_outlined), onPressed: () { //if(auth.status == Status.Authenticated){ cart.addItem( products[index].id.toString(), 10.0, products[index].name!.toString(), products[index].images![0].src!, 1, products[index].id.toString()); ScaffoldMessenger.of(context) .hideCurrentSnackBar(); ScaffoldMessenger.of(context) .showSnackBar( SnackBar( content: Text( S .of(context) .product_added_to_the_cart, ), duration: Duration(seconds: 2), action: SnackBarAction( label: S .of(context) .undo, onPressed: () { cart.reomveSingleItem( products[index] .id .toString()); }, ), ), ); }, ), ], ), Text(products[index].stockStatus!, style: TextStyle( color: Colors.orange, fontWeight: FontWeight.bold, fontSize: 15, ),), Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ RatingBar.builder( initialRating: products[index] .ratingCount! .toDouble(), minRating: 1, direction: Axis.horizontal, allowHalfRating: true, itemSize: 15.0, itemCount: 5, itemPadding: EdgeInsets.symmetric(horizontal: 4.0), itemBuilder: (context, _) => Icon( Icons.star, color: Colors.amber, ), onRatingUpdate: (rating) { print(rating); }, ), Text(products[index] .ratingCount! .toDouble() .toString()), ], ), ], ), ), ), ), ), ), ); }, ), ), ], ), ); }); } List<Tab> _tabs(List<CategoryModel> categoryModel) { List<Tab> tabs = []; for (CategoryModel category in categoryModel) { tabs.add(Tab( text: category.name, )); } return tabs; } وهذه كامل الملفات , ملف stream_products.dart
    import 'dart:async'; import '../../common/api_service.dart'; import '../../pages/contracts/contracts.dart'; import '../../models/Product.dart'; class StreamProductsBloc implements Disposable { List<ProductsModel>? products; final StreamController<List<ProductsModel>> _productsController = StreamController<List<ProductsModel>>.broadcast(); final StreamController<int> _categoryController = StreamController<int>.broadcast(); Stream<List<ProductsModel>> get productsStream => _productsController.stream; StreamSink<int> get fetchProducts => _categoryController.sink; Stream<int> get getProductsForCategoriescategory => _categoryController.stream; APIService? apiService; int categoryID = 0; StreamProductsBloc() { //this.categoryID = categoryID; this.products = []; apiService = APIService(); _productsController.add(products!); _categoryController.add(this.categoryID); _categoryController.stream.listen(_fetchCategoriesFromApi); } Future<void> _fetchCategoriesFromApi(int category) async { this.products = await apiService!.getProductsForCategories(category); _productsController.add(this.products!); } @override void dispose(){ _productsController.close(); _categoryController.close(); } } و ملف الواجهة ملف products_screen.dart 
    import 'package:bistore/providers/auth.dart'; import 'package:bistore/services/wishlist_provider.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:provider/provider.dart'; import '../../models/init_model.dart'; import '../../widgets/shimmer/shimmer_grid.dart'; import '../../generated/l10n.dart'; import '../../models/cart_model.dart'; import '../products/single_product.dart'; import '../../models/Product.dart'; import '../../models/category.dart'; import '../../utils/helper_api.dart'; import '../../pages/home/stream_products.dart'; class Products extends StatefulWidget { const Products({Key? key}) : super(key: key); @override _ProductsState createState() => _ProductsState(); } class _ProductsState extends State<Products> with AutomaticKeepAliveClientMixin, TickerProviderStateMixin { @override bool get wantKeepAlive => true; HelperApi helperApi = new HelperApi(); int currentIndex = 0; late TabController _tabController; var refreshKey = GlobalKey<RefreshIndicatorState>(); StreamProductsBloc streamProductsBloc = StreamProductsBloc(); late List<CategoryModel> productsCategories; @override void initState() { // ignore: todo // TODO: implement initState super.initState(); HelperApi().fetchCategories(1); } @override void dispose() { // ignore: todo // TODO: implement dispose super.dispose(); _tabController.dispose(); streamProductsBloc.dispose(); } @override // ignore: must_call_super Widget build(BuildContext context) { return FutureBuilder<List<CategoryModel>>( future: helperApi.fetchCategories(1), builder: (BuildContext context, AsyncSnapshot snapshot) { switch (snapshot.connectionState) { case ConnectionState.none: return Center( child: Text('No Connection'), ); case ConnectionState.waiting: case ConnectionState.active: return Scaffold( body: Center( child: CircularProgressIndicator(), ), ); case ConnectionState.done: if (snapshot.hasError) { print(snapshot.error); } else { if (!snapshot.hasData) { print('Data Not Found'); } else { this.productsCategories = snapshot.data; streamProductsBloc.fetchProducts .add(this.productsCategories[0].id!); return _categories(snapshot.data, context); } } break; } return Container(); }, ); } Widget _categories(List<CategoryModel> categoryModel, BuildContext context) { _tabController = TabController( initialIndex: 0, length: categoryModel.length, vsync: this, ); return Scaffold( appBar: AppBar( title: Text(S.of(context).products), bottom: TabBar( indicatorColor: Color(0XFF117182), indicatorWeight: 5, controller: _tabController, tabs: _tabs(categoryModel), isScrollable: true, onTap: (int index) { streamProductsBloc.fetchProducts .add(this.productsCategories[index].id!); }, ), ), body: Container( child: StreamBuilder( stream: streamProductsBloc.productsStream, builder: (context, AsyncSnapshot<List<ProductsModel>>? snapshot) { switch (snapshot!.connectionState) { case ConnectionState.none: // ignore: todo // TODO: Handle this case. return Center( child: CircularProgressIndicator(), ); case ConnectionState.waiting: // ignore: todo // TODO: Handle this case. return ShimmerGrid(); case ConnectionState.done: case ConnectionState.active: // ignore: todo // TODO: Handle this case. if (snapshot.hasError) { return Center( child: ShimmerGrid(), ); } else { if (!snapshot.hasData) { return ShimmerGrid(); } else { return _drawProducts(snapshot.data!, context); } } } }, ), ), ); } Widget _drawProducts(List<ProductsModel> products, BuildContext context) { final cart = Provider.of<Cart>(context, listen: false); var initModel = Provider.of<InitModel>(context, listen: false,); var auth = Provider.of<AuthProvider>(context, listen: false); return Consumer<WishListProvider>( builder: (BuildContext context, wishListData, child) { return Container( padding: EdgeInsets.only(top: 24), child: Column( children: [ Flexible( child: GridView.builder( gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( maxCrossAxisExtent: 200, childAspectRatio: 1 / 2, crossAxisSpacing: 20, mainAxisSpacing: 20), itemCount: products.length, itemBuilder: (context, index) { return Card( clipBehavior: Clip.hardEdge, elevation: 0.9, child: AnimationConfiguration.staggeredList( position: index, duration: const Duration(milliseconds: 375), child: SlideAnimation( verticalOffset: 50.0, child: FadeInAnimation( child: Padding( padding: const EdgeInsets.all(8.0), child: InkWell( onTap: () { _gotoSingleProduct(products[index], context); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Expanded( // ignore: unnecessary_null_comparison child: Stack( children: [ (products[index].images![0].src != null) ? Image.network( products[index].images![0].src!, width: MediaQuery .of(context) .size .width, height: MediaQuery .of(context) .size .height, fit: BoxFit.cover, ) : Image.asset( "assets/images/1.jpeg", width: MediaQuery .of(context) .size .width, height: MediaQuery .of(context) .size .height, fit: BoxFit.fill, ), Positioned.directional( textDirection: Directionality.of( context), child: Container( margin: EdgeInsets.symmetric( horizontal: 12.0, vertical: 10.0), decoration: BoxDecoration( color: Colors.grey[200], borderRadius: BorderRadius.circular(50.0)), child: IconButton( icon: Icon( Icons.favorite_outline), onPressed: () { //wishListData.getCount(products[index].id!, auth.id!); wishListData.addNewWishList( price: products[index] .price! .toString(), product: products[index] .name!, image: products[index] .images![0] .src!, productId: products[index] .id, userId: auth.id); ScaffoldMessenger.of(context) .showSnackBar( SnackBar( content: Text( S .of(context) .add_product_to_wishlist, ), duration: Duration( seconds: 2), ), ); }, iconSize: 20.0, ), ), ) ], ) ), Padding( padding: const EdgeInsets.all(8.0), child: Text( products[index].name!.substring(0, 10), style: TextStyle( color: Colors.black, fontWeight: FontWeight.bold, fontSize: 18.0, ), ), ), Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Padding( padding: const EdgeInsets.all(8.0), child: Text(initModel.currency! + products[index].price!, style: TextStyle( color: Colors.black, fontSize: 15.0, ), ), ), IconButton( icon: Icon( Icons.add_shopping_cart_outlined), onPressed: () { //if(auth.status == Status.Authenticated){ cart.addItem( products[index].id.toString(), 10.0, products[index].name!.toString(), products[index].images![0].src!, 1, products[index].id.toString()); ScaffoldMessenger.of(context) .hideCurrentSnackBar(); ScaffoldMessenger.of(context) .showSnackBar( SnackBar( content: Text( S .of(context) .product_added_to_the_cart, ), duration: Duration(seconds: 2), action: SnackBarAction( label: S .of(context) .undo, onPressed: () { cart.reomveSingleItem( products[index] .id .toString()); }, ), ), ); }, ), ], ), Text(products[index].stockStatus!, style: TextStyle( color: Colors.orange, fontWeight: FontWeight.bold, fontSize: 15, ),), Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ RatingBar.builder( initialRating: products[index] .ratingCount! .toDouble(), minRating: 1, direction: Axis.horizontal, allowHalfRating: true, itemSize: 15.0, itemCount: 5, itemPadding: EdgeInsets.symmetric(horizontal: 4.0), itemBuilder: (context, _) => Icon( Icons.star, color: Colors.amber, ), onRatingUpdate: (rating) { print(rating); }, ), Text(products[index] .ratingCount! .toDouble() .toString()), ], ), ], ), ), ), ), ), ), ); }, ), ), ], ), ); }); } List<Tab> _tabs(List<CategoryModel> categoryModel) { List<Tab> tabs = []; for (CategoryModel category in categoryModel) { tabs.add(Tab( text: category.name, )); } return tabs; } void _gotoSingleProduct( ProductsModel singleProductModel, BuildContext context) { Navigator.push( context, MaterialPageRoute( builder: (context) => SingleProduct(singleProductModel)), ); } } class ProductsList extends StatelessWidget { final List<ProductsModel> productsModel; ProductsList({Key? key, required this.productsModel}) : super(key: key); @override Widget build(BuildContext context) { return Column( children: [ Expanded( child: ListView.builder( scrollDirection: Axis.vertical, itemCount: productsModel.length, itemBuilder: (context, index) { return Text('${productsModel[index].name}'); }, ), ), ], ); } }  
  4. إجابة بلال زيادة سؤال في تغيير إتجاه الواجهة حسب اللغة في فلاتر كانت الإجابة المقبولة   
    يمكنك إضافة أي widget داخل Widget Stack بحيث تقوم باستخدام خاصية 
    Positioned.directional(), للتحكم في إتجاه النص بداخل هذا widget باستخدام خاصية 
    textDirection:Directionality.of(context), بحيث إذا كانت اللغة تبدأ من اليمين إلى اليسار , يتغير إتجاه النص من اليمين إلى اليسار , و من ثم إذا كانت اللغة تبدأ من اليسار إلى اليمين يتم تغيير إتجاه النص بناءً على ذلك .
    Stack( children: [ Image.asset( kSettingsImage, fit: BoxFit.cover, height: MediaQuery.of(context).size.height / 3, ), Positioned.directional( textDirection:Directionality.of(context), child: Text( '${S.of(context).settings}', style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 30.0, ), ), bottom: 10.0, start: 20.0, ), ], ), أو يمكنك استخدام Widget Builder بحيث يمكنك ايضا من تغيير إتجاه الواجهة من خلال خاصية 
    Directionality() builder: (context, child) { return Directionality( textDirection: TextDirection.rtl, child: child, ); },  
  5. إجابة بلال زيادة سؤال في هل يمكن نقل الدورة لحساب آخر كانت الإجابة المقبولة   
    يمكنك فتح تذكرة دعم فني من هنا , وأخبار الدعم الفني بذلك و سيعملون على حل مشكلتك بأسرع وقت ممكن.
  6. إجابة بلال زيادة سؤال في الفرق بين flutter inspector و flutter Emulator ؟ كانت الإجابة المقبولة   
    flutter inspector: يعد فاحص أدوات flutter أداة قوية لتصوير و استكشاف أشجار عناصر واجهة flutter. يستخدم إطار عمل flutter عناصر واجهة المستخدم باعتبارها اللبنة الأساسية لأي شيء بدءاً من عناصر التحكم مثل النصوص و الأزرار و المفاتيح , إلى عناصر التخطيط و هي Center, Column, Padding, Rows , يساعدك المراقب ( flutter inspector ) على استكشاف هذه العناصر والعمل على فهم المخطط الخاص بواجهة المستخدم أو تشخيص المشكلات التي تكون في تخطيط الصفحة.  يلجأ الكثير من المبرمجين إلى استخدام هذه الأداة لحل المشكلات التي قد تكون في الواجهة مما يوفر عليه عدم مراجعة كود تخطيط الصفحة من البداية وعدم اللجوء إلى تبديل عناصر قد تكون المشكلة بسبب عناصر أخرى غيرها.
    flutter Emulator: هو محاكي مثل أجهزة الموبايل android على نظام الكمبيوتر الخاص بك , بحيث يتيح لك تجربة تطبيقاتك عليه , ايضا يزود المحاكي المستخدم بعدة أجهزة ليتيح تجربة التطبيق على أكثر من جهاز موبايل بمختلف الإصدارات. يوفر هذا المحاكي عدة أمكانيات شبيهة بنظام الجوال, مثل محاكاة المكالمات الهاتفية و الرسائل الواردة و الصادرة , تحديد موقع الجهاز, أجهزة الاستشعار الأخرى, الوصول إلى متجر قوقل بلاي وغير ذلك الكثير, يعد أختبار تطبيقك على المحاكي اسرع و اسهل من أختباره على جهاز موبايل حقيقي.
  7. إجابة بلال زيادة سؤال في جعل الزر يتمدد حسب النص في فلاتر كانت الإجابة المقبولة   
    يمكنك استخدام Widgets 
    SizedBox() , Expanded()  بحيث تقوم بإضافة الزر داخل إحدى هذه Widgets بهذا الشكل 
    Expanded( child: TextButton( child: Text("Lang"), onPressed: (){} ), ) أو 
    SizedBox( child: TextButton( child: Text("Lang"), onPressed: (){} ), )  
  8. إجابة بلال زيادة سؤال في حل مشكلة تصميم pagination في لارافيل كانت الإجابة المقبولة   
    حاول معرفة أي إصدار bootstrap تستخدمه ومن ثم قم بوضع 
    pagination::bootstrap-4 مع تغيير إصدار البوتستراب 
    {{$questions->links('pagination::bootstrap-4')}} إذا لم يكن مجلد vendor داخل مجلد views فيمكنك استخدام الأمر التالي لتقوم بنشره داخل مجلد views 
    php artisan vendor:publish --tag=laravel-pagination ومن ثم يمكنك تخصيص ملف ترقيم الصفحات بوضع أي استايل تريده عن طريق وضع الملف الجديد 
    {{$questions->links('myfile')}}  
  9. إجابة بلال زيادة سؤال في العلاقات في لارافيل كانت الإجابة المقبولة   
    يمكنك إنشاء استعلام يمكنك من خلاله جلب بيانات التصنيف بهذه الطريقة 
    $sql = mysqli_query($connection, "SELECT * FROM category WHERE id = $category_id"); هذا استعلام عادي في PHP  
    أو من خلال laravel يمكنك إنشاء علاقة بين جدول posts , categorys  بحيث كل تصنيف لديه عدة منشورات و تكون العلاقة في ملفي Model الخاص بالجدولين و لنفرض أن جدول posts لديه ملف Post.php و جدول categories لديه ملف Category.php فالعلاقة ستكون باسم hasMany أي كل تصنيف يملك أكثر من منشور و في ملف Category.php يمكنك إضافة العلاقة التالية 
    public function posts(){ return $this->hasMany(Post::class); } وملف Post.php يحتوي على التالي 
    public function category(){ return $this->belongsTo(Category::class); } وخلال الاستعلام يمكنك جلب هذه العلاقة بهذه الطريقة 
    $posts = Post::with('category')->get(); أي قمنا من خلال with جلب العلاقة category و يمكنك جلب أكثر من علاقة بهذا الشكل 
    $posts = Post::with('category', 'اسم العلاقة الثانية')->get(); و من ثم يمكنك إنشاء حلقة تكرار بحيث تقوم بجلب المنشورات ومن خلال العلاقة category يمكنك الوصول إلى بيانات جدول categories بهذا الشكل 
    @foreach($posts->category() as $category) <h3>{{ $category->name ?? '' }}</h3> @endforeach  
  10. إجابة بلال زيادة سؤال في ما الفرق بين replaceOne و updateOne في mongodb؟ كانت الإجابة المقبولة   
    باستخدام replaceOne يمكنك فقط استبدال المستند بأكمله, بينما updateOne  تقوم بتحديث الحقول في  المستند.
    ايضا باستخدام replaceOne ستفقد الحقول الموجودة في المستند القديم غير الموجودة في المستند الجديد. 
    باستخدام updateOne يمكن إضافة حقول جديدة دون فقدان الحقول الموجودة في المستند القديم .
    هذه أمثلة توضح الفرق باستخدام replaceOne , updateOne . 
    { "id": ObjectId("123"), "code": 123 } باستخدام replaceOne بهذه الطريقة 
    replaceOne({ "id": ObjectId("123")}, {"code2": 321}); تكون نتيجة الكود كالتالي 
    { "id": ObjectId("123"), "code2": 321 } بينما باستخدام updateOne 
    updateOne({ "id": ObjectId("123"), }, {$set: {"code2": 321}}) تكون نتيجة الكود 
    { "id": ObjectId("123"), "code": 123, "code2": 321 }  
  11. إجابة بلال زيادة سؤال في ظهور الخطأ Insufficient free space for journal files في mongodb كانت الإجابة المقبولة   
    يمكنك إضافة ما يلي إلى ملف التكوين المقدم عند تشغيل 
    mongod --config mongod.conf لآخر إصدار من MongoDB 
    storage: mmapv1: smallFiles:true لإصدار 2.6 
    storage: smallFiles:true لإصدار 2.4 و الإصدارات التي أقل :
    smallFiles:true ثم قم فقط بتنفيذ mongod لقبول ملف التكوين الخاص بك , ويفترض أن يكون موقع ملف التكوين هو 
    /etc/mongodb.conf أو يمكنك تشغيل mongod باستخدام الأمر التالي 
    mongod --dbpath /data/db --smallfiles  
  12. إجابة بلال زيادة سؤال في تحديد option كخيار افتراضي في وسم select كانت الإجابة المقبولة   
    هل يمكنك وضع صورة للخطأ أو نص للخطأ الذي يظهر ؟, أو تأكد إسناد قيمة في خاصية value في وسم option بهذا الشكل 
    <select name="food"> <option value="0">الأختيار الأفتراضي</option> @foreach ($items as $item) @if ($loop->last) @isset($selected) <option value="{{$item->id ?? ''}}">{{$selected}}</option> @endisset @endif @endforeach </select> بحيث تقوم بوضع خارج loop وسم option افتراضي وتسند له قيمة معينة و في داخل loop يمكنك تنفيذ كود جلب البيانات , و من ثم إزالة خاصية selected حتى لا يحدث خطأ في عملية أختيار option الافتراضي, و في طبيعة الحال يقوم وسم select باختيار أول option كخيار افتراضي في حالة عدم تحديد أي option كخيار افتراضي عبر خاصية selected.
  13. إجابة بلال زيادة سؤال في لم افهم هذا الكود في بايثون كانت الإجابة المقبولة   
    علامة النسبة المئوية هي شائعة في العديد من لغات البرمجة, ليس فقط في Python , يحدد الباقي عند القسمة على رقمين , لذا في المثال يتم التحقق من الأرقام الزوجية إذا قسمت على 2, فإن الباقي يساوي 0 , فهو عدد زوجي .
    if i%2==0: تتحقق مما إذا كان الرقم زوجياً.
    for i in range(1, 101): if i%2==0: print(i) ونتيجة هذا الكود هي 
    2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100  
  14. إجابة بلال زيادة سؤال في إعادة توجيه المسار بناء على القيمة المرجعة من حقل الإدخال في لارافل كانت الإجابة المقبولة   
    هناك عدة طرق منها , يمكنك إنشاء مسار 
    Route::get('/search', 'GalleryController@search')->name('search'); بحيث يكون مسؤول عن عملية redirect , وتكون دالة search مهمتها جلب القيمة التي تم إرسالها بالفورم 
    public function search(Request $request) { return redirect()->route('getData', $request->name); } طبعاً نعرف مسار آخر لعرض الرابط كما نريد 
    http://127.0.0.1:8000/search/mobile وليكن المسار بهذا الشكل 
    Route::get('/search/{name}', 'GalleryController@foundData')->name('getData'); وتكون دالة foundData هي دالة عرض بيانات عن طريق القيمة التي نبحث عنها 
    public function foundData(Request $request, $name) { $books = Book::where('title', 'like', "%{$request->name}%")->paginate(12); $title = ' عرض نتائج البحث عن: ' . $request->name; return view('gallery', compact('books', 'title')); } ويكون form الإدخال بهذا الشكل 
    <form class="form-inline col-md-6 justify-content-center" action="{{ route('search') }}" method="GET"> <input type="text" class="form-control mx-sm-3 mb-2" name="name"> <button type="submit" class="btn btn-secondary mb-2">ابحث</button> </form> بحيث يكون نوع الإرسال من نوع GET و رابط التوجيه هو 
    {{ route('search') }} و حقل الإدخال يحمل خاصية 
    name="name" <input type="text" class="form-control mx-sm-3 mb-2" name="name">  
  15. إجابة بلال زيادة سؤال في سطر الأوامر وينداوز CMD كانت الإجابة المقبولة   
    لاحظ أن 
    %USERPROFILE%\ معناها هو مجلد user profile على الجهاز و هو يقصد به مجلد تعريف المستخدم الخاص بك في مجلد المستخدمين على محرك نظام windows الخاص بك , والذي يكون على معظم أجهزة الكمبيوتر على القرص C فلاحظ عندما قمت بتنفيذ هذا الأمر في cmd 
    cd %USERPROFILE%\ سيقوم بفتح المسار التالي 
    C:\Users\Bilal> ماذا لو أردنا إنشاء مجلد في هذا المسار نقوم باستخدام الأمر التالي 
    mkdir %USERPROFILE%\\TestFolder فسيقوم بإنشاء مجلد باسم TestFolder في المسار التالي على الحاسوب 
    C:\Users\Bilal> عندما كنت تستخدم الأمرين
    mkdir projects > cd projects لاحظ انه عندما تقوم بفتح cmd تلقائياً يكون المسار الموضوع هو مسار مجلد تعريف المستخدم 


  16. إجابة بلال زيادة سؤال في ظهور الخطأ unmet dependency في node.js كانت الإجابة المقبولة   
    تحتاج يدوياً إلى تثبيت وحدات المستوى الأعلى , التي تحتوي على التبعيات 
    npm install findup-sync@0.1.2 أو قم بإزالة مجلد node_modules باستخدام الأمر التالي 
    rm -rf node_modeules/ ثم تشغيل الأمر التالي لتنظيف الكاش 
    npm cache clean ثم أعد استخدام الأمر التالي 
    npm install  
  17. إجابة بلال زيادة سؤال في ظهور الخطأ Failed global initialization عند تنفيذ mongo في نظام Ubuntu كانت الإجابة المقبولة   
    يتم إنشاء الإعدادات المحلية المفقودة باستخدام لغة locale-gen, يمكن ضبط الإعدادات المحلية (إلى en_US.UTF-8) على النحو التالي: 
    export LANGUAGE=en_US.UTF-8 export LANG=en_US.UTF-8 export LC_ALL=en_US.UTF-8 locale-gen en_US.UTF-8 dpkg-reconfigure locales  
  18. إجابة بلال زيادة سؤال في كيف يمكنني إعادة view في مسار Laravel Octane كانت الإجابة المقبولة   
    يمكنك استخدام Route Class بهذا الشكل 
    retrun Illuminate\Routing\Router::toResponse($request, $response); أو يمكنك استخدام Facade بهذا الشكل 
    return Route::toReqponse($request, $response); هذا مثال محدد لِ Octane 
    Octane::route('GET', '/url', function($request) { return Route::toResponse($request, view('')); }); باستخدام هذا الأسلوب بإعادة أي شيء مثل array, model, string, redirect. إذا كنت تريد عرض معين فيمكنك استخدام 
    use Illuminate\Http\Response; Octane::route('GET', '/url', function() { return new Response(view('')); });  
  19. إجابة بلال زيادة سؤال في ماهي خطوات تحويل مشروع لارافل إلى Lumen؟ كانت الإجابة المقبولة   
    lumen هي نسخة مجردة من laravel و lumen لا يحتوي على جميع مميزات laravel و ايضا هناك خصائص غير موجودة على الإطلاق, ومن المهم عند تحويل مشروع الأخذ بعين الأعتبار :
    يجب ترحيل تعريفات المسار لأن Lumen يستخدم موجهًا مختلفًا لا يستخدم lumen ملف env. لذلك قد تلجأ إلى فك تعليق السطر التالي  Dotenv::load() في ملف 
    bootstrap\app.php  
    لا يتم ايضا تمكين الواجهات مثل DB, Mail, Queue ولتفعيلها يجب إزالة التعليق عن السطر التالي 
    $app->withFacades(); في ملف 
    bootstrap\app.php  
    ايضا يجب عليك تفعيل Eloquent من خلال إزالة التعليق عن السطر التالي 
    $app->withEloquent(); في ملف 
    bootstrap\app.php  
  20. إجابة بلال زيادة سؤال في ظهور خطأ عند تحديث composer في Laravel Forge كانت الإجابة المقبولة   
    في بيئة العمل المحلية الخاصة بك , يجب التحقق من ملف composer.json و التحقق من أي عنصر  في require يجب أن يكون ضمن require-dev و قم بنقله . 
    ثم أحذف ملف composer.lock و من ثم إعادة التحديث   
    composer update -vvv ومن ثم قم بأختبار مشروعك محلياً , وإذا كل شيء يعمل يمكنك نقل composer.lock الخاص بك إلى نظام التحكم في الإصدار الخاص بك وإعادة نشر التطبيق على Forge
  21. إجابة بلال زيادة سؤال في مشكلة عدم إطلاق الأحداث ضمن Lumen في لارافل كانت الإجابة المقبولة   
    ربما يجب عليك تحديث نسخة laravel lumen التي تعمل عليها و التأكد مرة أخرى من المشكلة , أو يمكنك إنشاء Mail Provider جديد ليتم استعماله بدلاً من Provider الأقتراضي في المسار التالي 
    app\Providers وليكن باسم MailServiceProvider.php 
    <?php namespace App\Providers; use Illuminate\Mail\Mailer; use Illuminate\Mail\MailServiceProvider as BaseProvider; class MailServiceProvider extends BaseProvider { protected function registerIlluminateMailer() { $this->app->singleton('mailer', function ($app) { $config = $app->make('config')->get('mail'); $mailer = new Mailer( $app['view'], $app['swift.mailer'], $app['events'] ); $mailer->setQueue($app['queue']); foreach (['from', 'reply_to', 'to'] as $type) { $this->setGlobalAddress($mailer, $config, $type); } return $mailer; }); $this->app->configure('mail'); $this->app->alias('mailer', \Illuminate\Contracts\Mail\Mailer::class); } } ثم عليك بتسجيل هذه Provider في ملف app.php الموجود بداخل مجلد bootstrap عن طريق إضافة السطر التالي 
    $app->register('\App\Providers\MailServiceProvider::class');  
     
  22. إجابة بلال زيادة سؤال في عدم تكرار تخزين رقم الجوال في فلاتر كانت الإجابة المقبولة   
    تمام , يمكن إنشاء هذا الريكويست الذي يفحص إذا كان الرقم موجود أو لا من خلال الاستعلام التالي 
    $findNumber = Number::where('phone', 'like', '%' . $number . '%')->first(); $findNumber = Number::where('phone', 'like', '%' . $number . '%')->get();  
  23. إجابة بلال زيادة سؤال في كيفية عمل التحقق ضمن Flutter - Form validation كانت الإجابة المقبولة   
    لماذا تريد عمل validation للموقع ؟ , بما أنك تقوم بأخذ lat, long يمكنك التأكد من أن الحقلين الذين تضع بهما lat, long غير فارغين , إذا أردت التأكد من أن lat, long صحيحين يمكنك استخدام حزمة geolocator بحيث عندما تقوم بتمرير lat, long إلى دالة LatLng بحيث تتأكد أنها ترجع position ولا لا , صراحة اول مرة أواجه مثل هذا الأمر بأن أقوم بعمل validation للموقع . 
    setState((){ currentPosition = LatLng(lat, long); });  
  24. إجابة بلال زيادة سؤال في إظهار نص بناء على ما يتم أختياره من dropdown في فلاتر كانت الإجابة المقبولة   
    يمكنك استخدام widget Inkwell بحيث تستطيع إسناد حدث الضغط على النص بحيث يمكنك إظهار و إخفاء النص بناء على للقيمة المخزنة في المتغير
  25. إجابة بلال زيادة سؤال في إخفاء listTile إذا تحقق شرط في فلاتر كانت الإجابة المقبولة   
    هي أفضل طريقة استخدام Provider , هل يمكنك إرفاق الملف الذي به المشكلة , أو يمكنك وضع متغير من نوع bool و متغير geter مثل 
    bool _isHide; bool get ishide => _isHide; وتقوم بعد إرسال البيانات تقوم بتغيير قيمة هذا المتغير و من ثم قبل listTile تقوم بفحص geter إذا قيمته مثلاً true تخفي البيانات , false يعني لا تختفي.
×
×
  • أضف...