Ember本地存储如何使用hasMany与async:控制器中的true? [英] Ember local-storage How to use hasMany with async: true in controllers?

查看:97
本文介绍了Ember本地存储如何使用hasMany与async:控制器中的true?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有localstorage-adapter的ember.js



这是一个JSbin的问题: http://jsbin.com/lejizo/9/edit?html,console,output



拥有这些模型:

  / *模型* / 
App.List = DS.Model .extend({
name:DS.attr('string'),
// DOES NOT WORK :: items:DS.hasMany('item')
items:DS.hasMany 'item',{async:true})
});

App.Item = DS.Model.extend({
name:DS.attr('string'),
list:DS.belongsTo('list')
});

如果您没有使 hasMany 异步。顺便说一下,数据位于 localstoarge 中。我初始化如下:

  var FIXTURES = {
'list':{
records:{
'1':{
id:'1',
名称:'列表',
项:['1','2']
} ,
'2':{
id:'2',
名称:'第二个列表',
items:['1','3']

}
},
'item':{
records:{
'1':{
id:'1',
name:'item 1',
list:'1'},
'2':{
id:'2',
name:'item 2'
列表:'1'
},
'3':{
id:'3',
名称:'项目3',
列表:'1'
}
}
}
}

localStorage.setItem('DS.LSAdapter',JSON.stringify(FIXTURES));

无论如何,制作项目:DS.hasMany('item',{async :true})使应用程序运行顺利。



问题是如果我尝试从控制器访问项目,它们不是一个对象,它们是只有一个承诺!这迫使我们使用以下方法:

  list.get('items')然后(function(items){//必须使用
items.forEach(function(item){
console.log(item.get('id'));
});
});

这对我来说似乎很尴尬,要经常注意 hasMany 关系,小心如何使用它们,而不是像任何其他关系一样使用相关对象。



这是正常还是我缺少什么?
有没有解决方法来定义它们async:true,因为所有的数据已经在本地存储?
我们应该在控制器中随时使用所有相关实体作为最佳做法吗?

解决方案


这对我来说似乎很尴尬,要经常注意hasMany关系,你使用它们,而不是像任何其他关系一样使用相关对象。


这将是尴尬的,这就是为什么你不必这样做;)在大多数情况下,Ember会自动监视属性更新并相应地传播。这意味着什么?这意味着你不应该担心价值是一个承诺;



简而言之,Ember使用特殊的承诺来观看属性更新。所以我们假设你有以下模板:

  {{#model.items中的每个项目}} 
{ item.name}}
{{/ each}}

如果 model.items 是一个异步的 hasMany 关系,Ember仍然会做正确的事情。当模板首先渲染时,将不会有数据。 属性进行更新。当它有更新(如承诺解决时),Ember将再次运行模板。这一次,数据将在那里,它将按照您的期望正常工作。



属性也是如此:



()$ {


$ b返回this.get('model.items')。 b $ b});
} .property('model.items。@ each')

此属性将返回第一次运行一个空数组。但是,当承诺解决时,Ember将再次运行该产品并产生您想要的结果。



在幕后,还有很多事情要做,需要担心,直到你进入一些更复杂的用例。如果您想了解更多信息,建议您查看以下资源:


  1. RSVP Promise库

  2. 不同步的Ember指南

  3. ObjectProxy ArrayProxy 课程

  4. PromiseProxyMixin 课程

编辑:例如,如果要修改关系,请添加一个新项目,执行以下操作:

  actions:{
addPost:function(post){
this.get('model.posts')然后(function(posts){
posts.addObject(post);
}) ;
}
}


I'm using ember.js with localstorage-adapter

Here is a JSbin with the issue: http://jsbin.com/lejizo/9/edit?html,console,output

Having these models:

/* Models */
App.List = DS.Model.extend({
    name: DS.attr('string'),
    // DOES NOT WORK:: items: DS.hasMany('item')
    items: DS.hasMany('item', {async: true})
});  

App.Item = DS.Model.extend({
    name: DS.attr('string'),
    list: DS.belongsTo('list')
    });

Ember data throws an error if you don't make the hasMany asynchronous. By the way, the data is in the localstoarge. I initialize it like this:

var FIXTURES = {
    'list': {
        records: {
            '1': { 
                id: '1', 
                name: 'The List', 
                items: ['1','2'] 
            },
            '2': { 
                id: '2', 
                name: 'The Second List', 
                items: ['1','3'] 
            }
        }
    },
    'item': {
        records: {
            '1': { 
                id: '1', 
                name: 'item 1', 
                list: '1' },
            '2': { 
                id: '2', 
                name: 'item 2', 
                list: '1' 
            },
            '3': { 
                id: '3', 
                name: 'item 3', 
                list: '1' 
            }
        }
    }
}

localStorage.setItem('DS.LSAdapter', JSON.stringify(FIXTURES));

Anyways, making items: DS.hasMany('item', {async: true}) make the application run smoothly.

The problem is that if I try to access the items from a Controller they are not an object, they are only a promise! This force us use the following approach:

list.get('items').then(function(items) { // must use then
    items.forEach(function(item){
        console.log(item.get('id'));
    });
});  

This seems awkward to me, to always watch out for the hasMany relationships and be careful how you use them, instead of just work with the related objects as for any other relationship..

Is this normal or am I missing something? Is there a workaround to not define them async: true, since all the data is already in the localstorage? Should we always use then in controllers for all related entities as a best practice?

解决方案

This seems awkward to me, to always watch out for the hasMany relationships and be careful how you use them, instead of just work with the related objects as for any other relationship..

That would be awkward, which is why you don't have to do that. ;) In most cases, Ember will automatically watch for property updates and propagate them accordingly. What does that mean? That means that you shouldn't worry that the value is a promise; use it as if it wasn't one.

In short, Ember uses a special kind of promise to watch for property updates. So let's say you have the following template:

{{#each item in model.items}}
    {{item.name}}
{{/each}}

If model.items is an asynchronous hasMany relationship, Ember will still do the right thing. When the template first renders, there will be no data. Your each loop will produce nothing. But Ember is going to watch the model.items property for updates. When it has an update (like when the promise resolves), Ember will run the template again. This time, the data will be there and it will work exactly as you expect.

The same holds true for properties:

function() {
    return this.get('model.items').filter(function(item) {
        return !!item;
    });
}.property('model.items.@each')

This property will return an empty array the first time it runs. But when the promise resolves, Ember will run the property again and produce the result you want.

Behind the scenes of that there's a lot going on, but you generally don't need to worry about that until you get into some more complicated use cases. If you'd like to know more, I suggest checking out these resources:

  1. The RSVP Promise library
  2. Ember's guide on asynchrony
  3. The ObjectProxy and ArrayProxy classes
  4. The PromiseProxyMixin class

EDIT: If you want to modify the relationship, for instance, add a new item, do something like this:

actions: {
    addPost: function(post) {
        this.get('model.posts').then(function(posts) {
            posts.addObject(post);
        });
    }
}

这篇关于Ember本地存储如何使用hasMany与async:控制器中的true?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆