как включить конструктор в Multiprovider 4.0.0 во флаттере - PullRequest
0 голосов
/ 02 апреля 2020

Я работаю в провайдере версии 3.0.0, и он показывает мне эту ошибку:

'builder' устарел и не должен использоваться. будет удален в 4.0.0, используйте обновление вместо. Попробуйте заменить использование устаревшего члена на replace.dart

, вот мой код main.dart:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'screens/auth_screen.dart';
import './screens/cart_screen.dart';
import './screens/products_overview_screen.dart';
import './screens/product_detail_screen.dart';
import './providers/products.dart';
import './providers/cart.dart';
import './providers/orders.dart';
import './screens/orders_screen.dart';
import './screens/user_products_screen.dart';
import './screens/edit_product_screen.dart';
import 'providers/Auth.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [

        ChangeNotifierProvider.value(
          value: Auth(),
          ),
       ChangeNotifierProxyProvider<Auth, Products>(  
         builder: (ctx, auth, previousProducts) => Products(
                auth.token,
                previousProducts == null ? [] : previousProducts.items,
              ),

        ),
        ChangeNotifierProvider.value(
          value: Cart(),
        ),
        ChangeNotifierProvider.value(
          value: Orders(),
        ),
      ],
      child: Consumer<Auth>(builder: (ctx, auth , _)=>MaterialApp(
          title: 'MyShop',
          theme: ThemeData(
            primarySwatch: Colors.purple,
            accentColor: Colors.deepOrange,
            fontFamily: 'Lato',
          ),
          home: auth.isAuth? ProductsOverviewScreen(): AuthScreen(),
          routes: {
            ProductDetailScreen.routeName: (ctx) => ProductDetailScreen(),
            CartScreen.routeName: (ctx) => CartScreen(),
            OrdersScreen.routeName: (ctx) => OrdersScreen(),
            UserProductsScreen.routeName: (ctx) => UserProductsScreen(),
            EditProductScreen.routeName: (ctx) => EditProductScreen(),
          }), ),

    );
  }
}

, вот мой код класса аутентификации

import 'dart:convert';
import 'package:flutter/widgets.dart';
import '../models/Exceptionhandle.dart';
import 'package:http/http.dart' as http;

class Auth with ChangeNotifier {
  String _token;
  DateTime _expiryDate;
  String _userId;

  bool get isAuth {
    return token != null;
  }

  String get token {
    if (_expiryDate != null &&
        _token != null &&
        _expiryDate.isAfter(DateTime.now())) {
      return _token;
    }
    return null;
  }

  Future<void> _authnticate(
      String email, String password, String urlSegment) async {
    final url =
        'https://www.googleapis.com/identitytoolkit/v3/relyingparty/$urlSegment?key=AIzaSyAt_rZWIJtr6pHX6sFipo9RDdpMadIpsYk';
    try {
      final response = await http.post(
        url,
        body: json.encode(
          {
            'email': email,
            'password': password,
            'returnSecureToken': true,
          },
        ),
      );
      final responseData = json.decode(response.body);
      if (responseData['error'] != null) {
        throw ExceptionHandle(responseData['error']['message']);
      }
      _token = responseData['idToken'];
      _userId = responseData['localId'];
      _expiryDate = DateTime.now().add(
        Duration(
          seconds: int.parse(
            responseData['expiresIn'],
          ),
        ),
      );
      notifyListeners();
    } catch (error) {
      throw error;
    }
  }

  Future<void> signup(String email, String password) async {
    return _authnticate(email, password, 'signupNewUser');
  }

  Future<void> login(String email, String password) async {
    return _authnticate(email, password, 'verifyPassword');
  }
}

и вот мой Код класса продуктов:

import 'dart:convert';
import '../models/Exceptionhandle.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

import './product.dart';

class Products with ChangeNotifier {

  List<Product> _items = [];

String authToken;
Products(this.authToken , this._items) ;
  List<Product> get items {
    return [..._items];
  }

  List<Product> get favoriteItems {
    return _items.where((prodItem) => prodItem.isFavorite).toList();
  }

  Product findById(String id) {
    return _items.firstWhere((prod) => prod.id == id);
  }

  Future<void> fetchAndSetProducts() async {
    const url = 'https://shopapp-76e9d.firebaseio.com/products.json';
    try {
      final response = await http.get(url);
      final extractData = json.decode(response.body) as Map<String, dynamic>;
      if (extractData == null) {
        return;
      }
      final List<Product> LoadedProducts = [];
      extractData.forEach((prodId, ProdData) {
        LoadedProducts.add(Product(
            id: prodId,
            title: ProdData['title'],
            description: ProdData['description'],
            imageUrl: ProdData['imageUrl'],
            isFavorite: ProdData['isFavorite'],
            price: ProdData['price']));
      });
      _items = LoadedProducts;
      notifyListeners();
    } catch (error) {
      throw error;
    }
  }

  Future<void> addProduct(Product product) async {
    const url = 'https://shopapp-76e9d.firebaseio.com/products.json';
    try {
      final response = await http.post(
        url,
        body: json.encode({
          'title': product.title,
          'description': product.description,
          'imageUrl': product.imageUrl,
          'price': product.price,
          'isFavorite': product.isFavorite,
        }),
      );
      final newProduct = Product(
        title: product.title,
        description: product.description,
        price: product.price,
        imageUrl: product.imageUrl,
        id: json.decode(response.body)['name'],
      );
      _items.add(newProduct);
      notifyListeners();
    } catch (error) {
      print(error);
      throw error;
    }
  }

  void updateProduct(String id, Product newProduct) async {
    final prodIndex = _items.indexWhere((prod) => prod.id == id);
    if (prodIndex >= 0) {
      final url = 'https://shopapp-76e9d.firebaseio.com/products/$id.json';
      await http.patch(url,
          body: json.encode({
            'title': newProduct.title,
            'description': newProduct.description,
            'imageUrl': newProduct.imageUrl,
            'price': newProduct.price,
          }));
      _items[prodIndex] = newProduct;
      notifyListeners();
    } else {
      print('...');
    }
  }

  Future<void> deleteProduct(String id) async {
    final url = 'https://shopapp-76e9d.firebaseio.com/products/$id.json';
    final existingProductIndex = _items.indexWhere((prod) => prod.id == id);
    var existingproduct = _items[existingProductIndex];
    _items.removeAt(existingProductIndex);
    notifyListeners();
    final response = await http.delete(url);
    if (response.statusCode >= 400) {
      _items.insert(existingProductIndex, existingproduct);
      notifyListeners();
      throw ExceptionHandle('Ops..!! Sorry Could Not Delete This Product.');
    }
    existingproduct = null;
  }
}

Может кто-нибудь подсказать мне, как использовать конструктор вместо обновления и создания?

Ответы [ 2 ]

0 голосов
/ 02 апреля 2020

Вы можете использовать его следующим образом:

ListView.builder(
              physics: NeverScrollableScrollPhysics(),
              scrollDirection: Axis.vertical,
              itemCount: rrr.length,
              itemBuilder: (ctx, index) => ChangeNotifierProvider.value(
                  value: rrr[index],
                      child: ChildItem()),
            ),

Информация о контенте поставщика находится в ChildItem()

0 голосов
/ 02 апреля 2020

Добавьте update к вашему ChangeNotifierProxyProvider и измените build на create.

ChangeNotifierProxyProvider<MyModel, MyChangeNotifier>(
  create: (_) => MyChangeNotifier(),
  update: (_, myModel, myNotifier) => myNotifier
    ..update(myModel),
  child: ...
);

См .: https://github.com/rrousselGit/provider/blob/master/README.md#ProxyProvider

и https://pub.dev/documentation/provider/latest/provider/ChangeNotifierProxyProvider-class.html

Редактировать:

Попробуйте это

ChangeNotifierProxyProvider<Auth, Products>(
    create: (c) => Products(Provider.of<Auth>(c, listen: false).token),
    update: (_, auth, products) => products.authToken = auth.token,
),
...