Dart 为什么不是';我更新的可观察列表是否反映在模板中?

Dart 为什么不是';我更新的可观察列表是否反映在模板中?,dart,polymer,dart-polymer,Dart,Polymer,Dart Polymer,我有: my-app community-list 在附加时,我的应用程序获取用户并加载app.user。同时,社区列表被附加(甚至在app.user加载之前),所以我还无法获得用户的星级社区。因此,我正在研究的解决方案如下 在社区列表中。已附加() 请注意,社区是社区列表中的一个可观察列表: @observable List communities = toObservable([]); 它最初填充在社区列表中。已附加() 总之,我甚至在拥有用户之前就加载了社区列表,但一旦拥有了用户,

我有:

my-app
  community-list
在附加时,我的应用程序获取用户并加载app.user。同时,社区列表被附加(甚至在app.user加载之前),所以我还无法获得用户的星级社区。因此,我正在研究的解决方案如下

在社区列表中。已附加()

请注意,社区是社区列表中的一个可观察列表:

@observable List communities = toObservable([]);
它最初填充在社区列表中。已附加()

总之,我甚至在拥有用户之前就加载了社区列表,但一旦拥有了用户,我想用userStarred=true/false更新社区列表中的每个社区(映射),然后在我的社区列表模板中使用

  • 唉,列表似乎没有更新。我如何做到这一点
  • 整个app.changes.listen业务都很昂贵。在这种情况下,正确的做法是什么?在我加载对象(如app.user)之前加载元素,这些对象将以某种方式修改它
  • (一)
    toList()
    创建列表的副本。您需要再次应用
    toObservable
    以获得可观察列表

    communities=toObservable(communities.reversed.toList());
    
    这也为
    社区
    分配了一个新列表,该列表由
    @observable
    覆盖。 我认为它无论如何都应该触发

    2) 您可以明确地更新您的社区。不必监听
    更改
    。您可以调用包含

    if(app.user!=null){
    getUserStarredCommunities();
    }
    
    每次更改列表时都会显式地执行

    社区发生更改时,您还可以为每个社区调用Firebase。我不知道Firebase,但似乎每次都会向服务器发送请求,这当然很昂贵。
    您应该记住,对于您已经进行的
    用户
    +
    社区
    组合,您应该使用记住的结果

    使用
    app.changes.listen
    您可以收听组件中任何
    @observable
    字段的任何更新。如果在
    社区
    旁边有其他可观察的字段,则可能会频繁调用此方法。 如果您只对
    社区的更改感兴趣
    ,则应将此代码放入如下方法中

    社区已更改(旧值、新值){
    如果(app.user!=null){
    getUserStarredCommunities();
    }
    }
    

    但更好的选择是不侦听更改和另一个方法名,并尽可能以上述状态显式调用它。

    toObservable()完成了这项任务。超级棒和及时的回答!我试试其他的东西,然后再转回来。非常感谢。Re:“每次更改列表时都可以显式调用一个方法。”问题是,如果我在getCommunities()中有getUserStarredCommunities(),它仍然会有第一次调用时没有用户的相同结果。一旦用户被加载,它就不会更新,因为元素已经被附加。如果我离开/分离该元素并返回,它就会工作,或者如果我使用app.changes.listen或communities changed技巧。我不理解另一种方式。我的建议不应该改变行为(我无法解释问题中未包含的可能影响行为的代码)。唯一的影响应该是
    getUserStarredCommunities
    可能会被调用的次数减少。我认为更重要的是不要重复调用
    db.Firebase
    ,这比在集合上迭代要昂贵得多。
      // This is triggered by an app.changes.listen.
      void getUserStarredCommunities() {
        // Determine if this user has starred the community.
        communities.forEach((community) {
          var starredCommunityRef = new db.Firebase(firebaseLocation + '/users/' + app.user.username + '/communities/' + community['id']);
          starredCommunityRef.onValue.listen((e) {
            if (e.snapshot.val() == null) {
              community['userStarred'] = false;
            } else {
              community['userStarred'] = true;
            }
          });
        });
      }
    
    @observable List communities = toObservable([]);
    
    getCommunities() {
        var f = new db.Firebase(firebaseLocation + '/communities');
    
        var communityRef = f.limit(20);
        communityRef.onChildAdded.listen((e) {
          var community = e.snapshot.val();
    
          // If no updated date, use the created date.
          if (community['updatedDate'] == null) {
            community['updatedDate'] = DateTime.parse(community['createdDate']);
          }
    
          // snapshot.name is Firebase's ID, i.e. "the name of the Firebase location"
          // So we'll add that to our local item list.
          community['id'] = e.snapshot.name();
    
          // Insert each new community into the list.
          communities.add(community);
    
          // Sort the list by the item's updatedDate, then reverse it.
          communities.sort((m1, m2) => m1["updatedDate"].compareTo(m2["updatedDate"]));
          communities = communities.reversed.toList();
        });
      }