【发布时间】:2019-09-08 17:58:47
【问题描述】:
我正在构建我的第一个 Flutter 应用程序,但很愚蠢,我从 MVVM 之类的复杂结构开始,我不太了解但已经尝试过。
这是我的文件夹结构:
lib
---models
------videos.dart
---repos
------videos.dart
---viewmodels
------videos.dart
main.dart (I know)
在我的main.dart 文件中,我使用 StreamBuilder 来获取视频列表,代码如下:
class Home extends StatelessWidget {
VideosBloc videosBloc = BlocProvider.getBloc<VideosBloc>();
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Expanded(
flex: 1,
child: CustomAppBar(),
),
Expanded(
flex: 9,
child: Container(
color: Theme.of(context).primaryColorDark,
child: StreamBuilder(
stream: videosBloc.videosStream,
builder: (context, snapshot) {
List<Video> videos = snapshot != null ? snapshot.data : [];
return ListView(
children: videos.map((video) {
return VideoContainer(video);
}).toList(),
);
},
),
),
)
],
);
}
}
有这个块文件:
import 'dart:async';
import 'package:bloc_pattern/bloc_pattern.dart';
import 'package:peeke_vines/models/videos.dart';
import 'package:peeke_vines/repositories/videos.dart';
import 'package:rxdart/rxdart.dart';
class VideosBloc extends BlocBase {
VideosBloc();
//Stream that receives a number and changes the count;
var _videosController =
BehaviorSubject<List<Video>>.seeded(VideosRepo().getVideos());
//output
Stream<List<Video>> get videosStream => _videosController.stream;
//input
Sink<List<Video>> get videosSink => _videosController.sink;
//dispose will be called automatically by closing its streams
@override
void dispose() {
_videosController.close();
super.dispose();
}
}
这个集团从存储库中获取这些数据
import 'package:peeke_vines/models/videos.dart';
class VideosRepo {
VideosRepo();
List<Video> videos = VideoModel().fetchVideos();
List<Video> getVideos() {
return [];
}
}
这个存储库目前只是从模型中获取数据,但稍后我将实现一个 Web 服务来从以下位置获取数据:
import 'package:meta/meta.dart';
class VideoModel {
List<Video> fetchVideos() {
return [
Video(
video: 'assets/videos/main.wmv',
title: 'Peeke Vines Video Title',
date: '2 Days ago',
thumbnail: 'assets/thumbnails/1.jpg',
duration: 13.5),
Video(
video: 'assets/videos/main.wmv',
title: 'Peeke Vines Video Title',
date: '2 Days ago',
thumbnail: 'assets/thumbnails/2.jpg',
duration: 13.5),
Video(
video: 'assets/videos/main.wmv',
title: 'Peeke Vines Video Title',
date: '2 Days ago',
thumbnail: 'assets/thumbnails/1.jpg',
duration: 13.5)
];
}
}
class Video {
String video, title, date, thumbnail;
double duration;
Video(
{@required this.video,
@required this.title,
@required this.date,
@required this.thumbnail,
@required this.duration});
}
现在,每当我使用以下行在 main.dart 文件中导入 bloc 时:
VideosBloc videosBloc = BlocProvider.getBloc<VideosBloc>();
我收到此错误:
I/flutter ( 4338): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 4338): The following NoSuchMethodError was thrown building MyApp(dirty):
I/flutter ( 4338): Class 'NoSuchMethodError' has no instance getter 'message'.
I/flutter ( 4338): Receiver: Instance of 'NoSuchMethodError'
I/flutter ( 4338): Tried calling: message
I/flutter ( 4338):
I/flutter ( 4338): When the exception was thrown, this was the stack:
I/flutter ( 4338): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:50:5)
I/flutter ( 4338): #1 BlocProvider.getBloc (package:bloc_pattern/src/bloc_provider.dart:47:12)
I/flutter ( 4338): #2 new Home (package:peeke_vines/main.dart:35:40)
I/flutter ( 4338): #3 MyApp.build (package:peeke_vines/main.dart:21:20)
I/flutter ( 4338): #4 StatelessElement.build (package:flutter/src/widgets/framework.dart:3974:28)
I/flutter ( 4338): #5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3924:15)
I/flutter ( 4338): #6 Element.rebuild (package:flutter/src/widgets/framework.dart:3721:5)
I/flutter ( 4338): #7 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3907:5)
I/flutter ( 4338): #8 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3902:5)
I/flutter ( 4338): #9 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3084:14)
I/flutter ( 4338): #10 Element.updateChild (package:flutter/src/widgets/framework.dart:2887:12)
I/flutter ( 4338): #11 RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:939:16)
I/flutter ( 4338): #12 RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:910:5)
I/flutter ( 4338): #13 RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure> (package:flutter/src/widgets/binding.dart:856:17)
I/flutter ( 4338): #14 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2320:19)
I/flutter ( 4338): #15 RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:855:13)
你能告诉我为什么会出现这个错误吗?
【问题讨论】:
-
您在 MaterialApp 上注册了
VideosBloc吗? -
@Martyns 你能详细说明一下,我该怎么做,我对此非常陌生,但了解一些事情。
-
我的意思是文档中写着“现在在 MaterialApp 之前添加 BlocProvider 小部件”的部分 pub.dev/packages/bloc_pattern 我建议您查看不需要 pub 包的 bloc 模式,您将了解核心概念更好。但基本上,如果没有在小部件树的某处“提供”VideoBloc,您将无法获得它。
-
哦,我认为问题可能是试图让 Bloc 超出构建方法。尝试在构建方法的开头获取它。
-
很高兴听到它成功了!