2016-06-10 2 views
0

Я изо всех сил пытаюсь выполнить обещанные данные Сервиса в Маршруте. Проблема возникает, когда я перехожу к Маршруту в приложении init; то есть, если я загружаю приложение, то переход, все в порядке, потому что обещание уже выполнено, но если я удалю перезагрузку браузера на этом маршруте, строки нарушения не будут выполняться. Служба:Доступ к обещанию услуги с маршрута

// services/lime-core.js 
import Ember from 'ember'; 

export default Ember.Service.extend({ 
    store: Ember.inject.service(), 
    resources: null, 

    init() { 
    this.set('resources', []); 

    this.get('store').findAll('resource').then(resources => { 
     this.set('resources', resources); 
    }); 
    } 
}); 

Эта услуга прекрасно работает в шаблоне, предполагая, что я ввел услугу в компонент. Я эту службу в маршрут следующим образом: (предположим, что slug имеет значимую величину)

// dashboard/route.js 
export default Ember.Route.extend({ 
    limeCore: Ember.service.inject(), 
    ... 
    model(params) { 
    ... 
    this.set('resource', this.get('limeCore.resources').findBy('slug', slug)); 
    ... 
    } 
} 

Когда model() хук вызывается, init() метод в limeCore сервиса все еще ждет обещание выполнить. Я пытался быть умным, но изменить код, чтобы что-то вроде:

this.get('limeCore.resources').then(resources => { 
    this.set('resource', resources.findBy('slug', slug)) 
}); 

не работает, потому что this.get('limeCore.resources') не возвращает Promise. Эта логика должна быть в маршруте (т. Е. Не может быть перемещена в шаблон), потому что я зависим от значения slug, чтобы определить идентификатор, который загружает другой набор данных ember.

Опять же, этот код работает правильно, как только обещание выполнено, то есть при дальнейшем переходе на этот маршрут, но не при загрузке первоначального приложения.

Я уверен, что есть правильный способ сделать это ... либо Служба должна вернуть обещание (хотя оно еще можно использовать в шаблонах), либо мне нужно убедиться, что обещание выполнено до Route.model() метод может быть выполнен.

Спасибо!

ответ

0

Я думаю, что мой вопрос был плохо сформулирован, поэтому я извиняюсь перед читателем за это. Это произошло потому, что, если я собираюсь задать вопрос, это часто, потому что у меня возникают проблемы с выражением проблемы.

Предлагаемый выше подход не помог мне, хотя он дал несколько полезных советов.Существенным требованием было то, что (как я упоминал в комментарии) мне нужно было использовать значение resource.id в запросе модели. подход к Кричану обратился к этому вопросу, но мой вопрос недостаточно показал, насколько сложным был метод model().

Неписаное второе требование заключалось в том, что запрос ajax выполняется только один раз, поскольку данные редко меняются и требуются во многих местах при загрузке приложения.

В конце концов, я смог использовать смесь подхода к Кричану - создание метода limeCore.getResource(), который загружает данные в Promise, а затем требует этого обещания в моем маршруте beforeModel(). Главное, что я понял, было то, что beforeModel(), как и model(), будет ждать, пока Promise не разрешит, прежде чем вызвать следующий крючок. В моем приложении model() никогда не должен запускаться до тех пор, пока эти основные объекты не будут загружены (model() зависит от них), поэтому имеет смысл загрузить их ранее. Возможно, есть более элегантный подход (который я открыт для слушания), но в этот момент я чувствую, что проблема решена!

// services/lime-core.js 
import Ember from 'ember'; 

export default Ember.Service.extend({ 
    store: Ember.inject.service(), 
    resources: null, 
    clients: null, 

    init() { 
    this.set('resources', []); 
    this.set('clients', []); 
    }, 

    // getCoreObjects() needs to be called at least once before the resources, clients and projects are available in the application. Ideally this method will be called in the route's beforeModel() hook. It cannot be called from the application route's beforeModel() hook because the code will not succeed if the user isn't authenticated. 
    getCoreObjects() { 
    if (this.get('resources').length === 0 || this.get('clients').length === 0) { 
     return Ember.RSVP.hash({ 
     resources: this.get('store').findAll('resource').then(resources => { 
      this.set('resources', resources); 
     }), 
     clients: this.get('store').findAll('client', {include: 'projects'}).then(clients => { 
      this.set('clients', clients); 
     }) 
     }); 
    } else { 
     return Ember.RSVP.hash({}); 
    } 
    } 
}); 

и в моем маршруте:

// routes/dashboard.js 
import Ember from 'ember'; 
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin'; 

export default Ember.Route.extend(AuthenticatedRouteMixin, { 
    limeCore: Ember.inject.service(), 
    session: Ember.inject.service(), 
    ... 
    beforeModel(transition) { 
    this._super(...arguments); 
    if (this.get('session.isAuthenticated')) { 
     return this.get('limeCore').getCoreObjects(); 
    } 
    }, 

    model(params) { 
    ... 
    this.set('resource', this.store.peekAll('resource').findBy('slug', slug)); 
    ... 
    return this.store.query('artifact', {'resource-id': this.get('resource.id')}); 
    } 
} 
0

подход, который я хотел бы использовать

app/misc/lime_core.js 

function getResources(store) { 
    return store.findAll('resource') 
} 

export { getResources }; 

случайный маршрут

import { getResources } from 'app/misc/lime_core'; 

export default Ember.Route.extend({ 
    model: function() { 
    const store = this.get('store'); 
    const sourcePromise = getResources(store); 
    }  
}) 

Но если вы все еще ищете сервис подхода я хотел бы использовать его как этот

export default Ember.Service.extend({ 
    resources: null, 
    store: Ember.inject.service(), 


    getResources: function() { 
    return this.get('store').findAll('source') 
    } 
}); 

маршрут

limeCore: Ember.inject.service(), 

    model: function() { 
     const store = this.get('store'); 
     const sourcePromise = this.get('limeCore').getResources(); // sourcePromise.then(... 

    } 

"модель() результат метод моего маршрута зависит от идентификатора ресурса"

model: function() { 
     this.get('limeCore').getResources().then(sources => { 
      return Ember.RSVP.hash({ 
       artifact: store.find('artifact', { source: source.get('firstObject.id)}) 
      }) 
     }) 
    } 

или раствор 2

 model: function() { 
      return Ember.RSVP.hash({ 
        artifact: this.get('limeCore').getResources().then(sources => { 
         return store.find('artifact', {source: xx}) 
        }) 
       }) 
      }) 
     } 

Кроме того, ваша функция GetResources может быть изменена по вашим критериям

function getResources(store) { 
     return store.findAll('resource').then(r => r.findBy('id', 1)) 
} 
+0

Хотя я не пробовал еще (это немного поздно здесь), я не уверен, что этот подход будет работать. Результат метода 'model()' моего маршрута зависит от идентификатора ресурса: 'return this.store.query ('artifact', {'resource-id': resource.id})'. Как метод 'model()' возвращает этот последующий запрос, если он работает в блоке 'then()'? – pauldoerwald

+0

Добавленное решение для вашей проблемы, вопрос никогда не утверждал, что вы столкнулись с такой проблемой. –

+0

Надеюсь, вы сможете создать свой ответ на основе моего. Не могу на самом деле сказать твою точную утику + –

Смежные вопросы