javascript - 如何在组件的复选框更改时异步加载数据并将其附加到模型?

标签 javascript facebook asynchronous ember.js

我目前正在开发一个 ember 应用程序,它有两个组件。

一个组件代表一张 map ,另一个组件代表一个好友列表。

两个组件都放置在同一个 Handlebars 模板中。

我试图实现的是,用户可以选中friendslist组件中的复选框,并在下一步中从facebook异步加载他或她的帖子(好友本身已经加载到beforeModel钩子(Hook)中)。这些异步加载的帖子应附加到模型中已存在的 friend 对象中。之后, map 组件应该收到有关更改的通知并刷新自身或调用将在 map 上绘制点的函数。

目前,我正在尝试设置单个 friend 的选中属性(这与附加帖子的方法相同,但现在会更容易):

// index.hbs
{{map-widget posts=model.posts friends=model.friends}}
{{friends-list checkedFriend='checkedFriend' friends=model.friends}}

// friends-list.hbs (component)
<ul>
  {{#each friends as |friend|}}
    <li>
      {{input type="checkbox" id=friend.facebookID checked=friend.checked change=(action checkedFriend)}}   <p>{{friend.name}}</p>
    </li>
  {{/each}}
</ul>

// friends-list.js (component)
import Ember from 'ember';

export default Ember.Component.extend({

  actions: {
    checkedFriend: function () {
      this.sendAction('checkedFriend');
    }
  }
});

// index.js (route)
export default Ember.Route.extend(AuthenticatedRouteMixin, {
...
  model: function() {
    return Ember.RSVP.hash({
      posts: this.get('currentUserPosts'),
      friends: this.get('friends')
    });
  },

  actions: {
    checkedFriend: function () {
      // Update just the first friend here to see if the approach works
      // Get the friends array from the model
      const model = this.controller.get('model');
      const friends = model.friends;

      // Update the friend
      Ember.set(friends[0], 'checked', true);

      // Map component receives an update here,
      // but "DEPRECATION: You modified (mut model.friends) twice in a single render." warning occurs
      this.set('friends', friends);
    }
  }
})

目前的方法或多或少有效。但是,我收到了折旧警告,指出我在一次渲染中修改了模型两次,在我看来,这是我这边设计不佳的迹象。

我想知道的是,完成上述任务的好方法是什么样的。如果我已经走在正确的道路上,如果有人能告诉我为什么会出现这种双重渲染错误,我会很高兴。

核心问题是如何正确更新模型,以及如何通知组件,特别是没有设置更改操作的组件,以便刷新这些组件。

提前谢谢您。

最佳答案

您可以创建一个类 - FriendEntry。通过调用它的构造函数,您将收到 FriendEntry 的一个实例。现在您将修改实例而不是原始记录(这确实是不对的)。

var FriendEntry = Ember.Object.extend({
    init: function() {
        this._super(...arguments);
        this.set('somethingFriendly', true);
    }
});

export default Ember.Controller.extend({
      friendsEntries: Ember.computed.map('model.friends', function(friend) {
          // Call the constructor
          return FriendEntry.create({
               friend: friend,
               checked: false,
               posts: []
          })
      })
});

好吧,你的组件看起来像这样。

{{friends-list checkedFriend='changeFriendCheckedStatus' entries=friendEntries}}


// friends-list.hbs (component)
<ul>
  {{#each entries as |entry|}}

      {{input type="checkbox" checked=entry.friend.checked change=(action checkedFriend entry)}}   <p>{{entry.friend.name}}</p>

  {{/each}}
</ul>

// friends-list.js (component)
import Ember from 'ember';

export default Ember.Component.extend({

  actions: {
    checkedFriend: function (entry) {
      this.sendAction('checkedFriend', entry);
    }
  }
});

返回 Controller

actions: {
   changeFriendCheckedStatus(friendEntry) {
         ic.ajax.request(API.HOST + '/someUrlForPosts/' + friendEntry.get('id)).then(givenFriendPosts => {
              entry.get('posts').pushObjects(givenFriendPosts);          
         }) 
   }
}

如果我理解正确的话,你有 2 个模特是我的 friend 和帖子 (DS.belongsTo('friend'))。您需要将两者封装到friendEntry (friend, posts) 中。

所以你的 map 小部件也会像这样 {{map-widgetfriendEntries=friendEntries}}

您可以像这样封装它们,而不是在模型中查询帖子。

    friendsEntries: function() {    
           return DS.PromiseArray.create({
                  promise: Ember.RSVP.all(this.get('model.friends')).then(friends => {
                    return friends.map(friend => {
                        return FriendEntry.create({
                          friend: friend,
                          checked: false,
                          posts: store.query('posts', { friend: friend.get('id') }
                       });  
                    }); 
                  })
          });
   }.property('model.friends.[]')

关于javascript - 如何在组件的复选框更改时异步加载数据并将其附加到模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37701422/

相关文章:

javascript - 上传带有预览的图像

javascript - 输入上的 onChange 事件返回 'Cannot read property search of undefined'

javascript - html 嵌入标签视频事件

android - 错误膨胀类 com.facebook.drawee.view.SimpleDraweeView

C++ std::async 在主线程上运行

javascript - Node.js 异步 : How to combine multiple iterators with map?

javascript - 如何使用 javascript es6 将数组插入到 Spanner 数据库的列中

facebook - 通过其他人不可见的应用程序作为页面发布到页面墙

javascript - 如何从发送按钮获取 Facebook 消息内容?

javascript - 如何在 cycle js 中从 JSON 数组创建组件