簡體   English   中英

Flutter Riverpod context.read(providerref) 在 Widget 的兩個不同函數中調用時不會給出相同的 stateNotifier 引用

[英]Flutter Riverpod context.read(providerref) doesn't give same reference of stateNotifier when call in two different functions of a Widget

我正在設置在視圖模型類中聲明的變量值,該類是一個 StateNotifier,在小部件的函數內。 當我嘗試從同一小部件​​的不同函數訪問這些變量的值時,它們的值為空。 我已經調試了代碼來驗證第一個函數是否正確設置了值。

任何幫助將不勝感激。

這是我的 StateNotifier 的簡化版本

class ProductViewModel extends StateNotifier<ProductState> {
  String errorMessage;

  Product product;

  final ProductService productService;
  final CategoryService categoryService;
  final BrandService brandService;
  final TranslatorService translatorService;
  final ProductOptionsViewModel productOptionsViewModel;
  final ProductVariantViewModel productVariantViewModel;

  ProductViewModel(this.productService, this.categoryService, this.brandService, this.translatorService,
      this.productOptionsViewModel, this.productVariantViewModel)
      : super(ProductInitial());

  String productId;
  List<SizeEnum> _sizes;
  String _selectedBrand;
  String _selectedCategory;
  String _selectedStore;
  String _productName;
  String _productIntlName;
  String _sku;

  String get selectedBrand => _selectedBrand;

  set selectedBrand(String value) {
    _selectedBrand = value;
  }  

  String get selectedCategory => _selectedCategory;

  set selectedCategory(String value) {
    _selectedCategory = value;
  }

  String get selectedStore => _selectedStore;

  set selectedStore(String value) {
    _selectedStore = value;
  }

  String get productName => _productName;

  set productName(String value) {
    _productName = value;
  }

  String get productIntlName => _productIntlName;

  set productIntlName(String value) {
    _productIntlName = value;
  }

  String get sku => _sku;

  set sku(String value) {
    _sku = value;
  }

  Future<bool> saveProductDetails() async {
    bool isSave = false;
    bool imageSaved = await saveProductImage();
    if (!imageSaved) return imageSaved;
    List<String> searchKeywords = indexProductName(_productName);
    List<String> searchTag1 = _searchTag1 != null ? indexProductName(_searchTag1) : null;
    List<String> searchTag2 = _searchTag2 != null ? indexProductName(_searchTag2) : null;
    List<String> searchTag3 = _searchTag3 != null ? indexProductName(_searchTag3) : null;
    if (deal != null && _dealsAddedDateTime == null) {
      _dealsAddedDateTime = DateTime.now();
    }
    print(productOptionsViewModel.toString());


    Product _product = Product(
        productId: productId,
        name: _productName,
        intlName: _productIntlName,
        category: FirebaseFirestore.instance.doc(_selectedCategory),
        brand: FirebaseFirestore.instance.doc(_selectedBrand),
        sku: _sku,
        quantity: _quantity,
        price: _price,
        containSizes: productOptionsViewModel.sizes,
        containColors: productOptionsViewModel.colors,
        accessory: productOptionsViewModel.accessory ,
        salesTaxApplicable: productOptionsViewModel.salesTax,
    );

    isSave = await productService.saveProduct(_product);
    if (!isSave) {
      errorMessage = "Error in saving product information";
    } else {
      productId = productService.newProductId;
    }
   
    return isSave;
  } 
}

StateNotifierProvider 聲明

final productViewModelProvider = StateNotifierProvider.autoDispose<ProductViewModel,ProductState>((ref) => ProductViewModel(
    ref.watch(productServiceProvider),
    ref.watch(categoryServiceProvider),
    ref.watch(brandServiceProvider),
    ref.watch(translatorServiceProvider),
    ref.watch(productOptionsViewModelProvider),
    ref.watch(productVariantViewModelProvider)));

UI 函數 我在 validateProduct 中設置值並在 saveProductDetails 中再次讀取值。

  Future<bool> validateProduct() async {
    if (_formKey.currentState.validate()) {
      _formKey.currentState.save();
      final model = context.read(productViewModelProvider.notifier);
      final storeViewModel = context.read(storeViewModelProvider.notifier);
      var _store = await storeViewModel.getMyStore();
      model.productName = _productName;
      model.productIntlName = _productIntlName;
      model.sku = _sku;
      model.quantity = _quantity;
      model.price = _price;
      model.selectedBrand = _selectedBrand;
      model.selectedCategory = _selectedCategory;
      model.selectedStore = _storeCode;
      model.description = _productDescription;
      model.manufacturerLink = _manufacturerLink;
      model.searchTag1 = _searchTag1;
      model.searchTag2 = _searchTag2;
      model.searchTag3 = _searchTag3;
      if (model.addedDateTime == null) {
        model.addedDateTime = DateTime.now();
      }
      if (_storeCode == null) {
        _storeCode = _store.store;
      }
      if (model.selectedStore == null) {
        model.selectedStore = _storeCode;
      }
      return true;
    }
    else return false;
  }


 Future<bool> saveProductDetails() async {
    final model = context.read(productViewModelProvider.notifier);

    bool isProductSaved = await model.saveProductDetails();
    if (isProductSaved) {
      if (_isProductExist) {
        displayMessage(context, "Product Information Updated");
      } else
        displayMessage(context, "Product Information Saved");

      _formSaved = true;
      isFormChanged = false;
      return true;
    } else if (isProductSaved == false) {
      _formSaved = false;
      displayMessage(context, model.errorMessage);
    }

    return isProductSaved;
  }

狀態

abstract class ProductState {
  const ProductState();
}

class ProductInitial extends ProductState {
  const ProductInitial();
}

class ProductLoading extends ProductState {
  const ProductLoading();
}

class ProductLoaded extends ProductState {
  final Product product;

  ProductLoaded(this.product);

  @override
  bool operator ==(Object other) =>
      identical(this, other) || other is ProductLoaded && runtimeType == other.runtimeType && product == other.product;

  @override
  int get hashCode => product.hashCode;
}

class ProductSaving extends ProductState {
  const ProductSaving();
}

class ProductSaved extends ProductState {
  final Product product;

  ProductSaved(this.product);

  @override
  bool operator ==(Object other) =>
      identical(this, other) || other is ProductSaved && runtimeType == other.runtimeType && product == other.product;

  @override
  int get hashCode => product.hashCode;
}

class ProductError extends ProductState {
  final String errorMessage;

  ProductError(this.errorMessage);
}

刪除 .autoDispose 修飾符

final productViewModelProvider = StateNotifierProvider<ProductViewModel,ProductState>((ref) => ProductViewModel(
ref.watch(productServiceProvider),
ref.watch(categoryServiceProvider),
ref.watch(brandServiceProvider),
ref.watch(translatorServiceProvider),
ref.watch(productOptionsViewModelProvider),
ref.watch(productVariantViewModelProvider)));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM