首页 > 解决方案 > Flutter Riverpod context.read(providerref) 在调用 Widget 的两个不同函数时没有给出相同的 stateNotifier 引用

问题描述

我正在设置在视图模型类中声明的变量的值,该类是 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);
}

标签: flutterdartstateproviderriverpod

解决方案


移除 .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)));

推荐阅读