Ember理解路由/控制器之间的执行流程

时间:2016-01-19 08:12:00

标签: javascript ajax ember.js ember-cli rsvp-promise

我有一个“盒子”路线/控制器如下;

export default Ember.Controller.extend({
    initialized: false,
    type: 'P',
    status: 'done',
    layouts: null,
    toggleFltr: null,
    gridVals: Ember.computed.alias('model.gridParas'),
    gridParas: Ember.computed('myServerPars', function() {
        this.set('gridVals.serverParas', this.get('myServerPars'));
        this.filterCols();

        if (!this.get('initialized')) {
            this.toggleProperty('initialized');
        } else {
            Ember.run.scheduleOnce('afterRender', this, this.refreshBox);
        }

        return this.get('gridVals');
    }),
    filterCols: function()
    {
        this.set('gridVals.layout', this.get('layouts')[this.get('type')]);
    },
    myServerPars: function() {
        // Code to set serverParas
        return serverParas;
    }.property('type', 'status', 'toggleFltr'),
    refreshBox: function(){
        // Code to trigger refresh grid
    }
});

我的路线看起来像;

export default Ember.Route.extend({
    selectedRows: '',
    selectedCount: 0,
    rawResponse: {},
    model: function() {
        var compObj = {};
        compObj.gridParas = this.get('gridParas');
        return compObj;
    },
    activate: function() {
        var self = this;
        self.layouts = {};

        var someData = {attr1:"I"};
        var promise = this.doPost(someData, '/myService1', false); // Sync request (Is there some way I can make this work using "async")
        promise.then(function(response) {       
            // Code to use response & set self.layouts
            self.controllerFor(self.routeName).set('layouts', self.layouts);
        });
    },
    gridParas: function() {
        var self = this;
        var returnObj = {};
        returnObj.url = '/myService2';
        returnObj.beforeLoadComplete = function(records) {          
            // Code to use response & set records
            return records;
        };
        return returnObj;
    }.property(),   
    actions: {      
    }
});

我的模板看起来像

{{my-grid params=this.gridParas elementId='myGrid'}}

我的doPost方法如下所示;

doPost: function(postData, requestUrl, isAsync){
    requestUrl = this.getURL(requestUrl);
    isAsync = (isAsync == undefined) ? true : isAsync;
    var promise = new Ember.RSVP.Promise(function(resolve, reject) {
        return $.ajax({
            // settings
        }).success(resolve).error(reject);

    });
    return promise;
  }

鉴于上述设置,我想了解执行的流程/顺序(即不同的钩子)。 我试图调试,它不断从一个类跳到另一个类。 另外,2个具体问题;

  
      
  1. 我原本期待“激活”钩子最初被解雇,但发现事实并非如此。它首先执行“gridParas”钩子   即在“激活”钩子之前。是因为“gridParas”   在模板中指定?

  2.   
  3. 当我为/ myService1执行this.doPost()时,它必须是“同步”请求,否则执行流程会发生变化,我会收到错误。   其实我想要filterCols()控制器里面的代码,即   this.set('gridVals.layout',this.get('layouts')[this.get('type')])来   只有在收到回复后才能执行   / myService1。但是,截至目前,我必须使用“同步”请求   那么,否则使用“async”,执行将移至filterCols()和   因为我还没有回复,所以会引发错误。

  4.   

添加,我正在使用Ember v 2.0

2 个答案:

答案 0 :(得分:2)

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid x:Name="SearchBoxContainer"> <AutoSuggestBox PlaceholderText="Type a topic name" Margin="8" QueryIcon="Find" DisplayMemberPath="Title" TextChanged="AutoSuggestBox_TextChanged" QuerySubmitted="AutoSuggestBox_QuerySubmitted" SuggestionChosen="AutoSuggestBox_SuggestionChosen" ItemsSource="{Binding MatchingTopics}" /> </Grid> </Grid> activate()beforeModel挂钩之后触发
  1. model ...因为这3个挂钩被认为是“验证阶段”(确定路线是否会解决)。需要说明的是,此路径挂钩与在模板中使用afterModel无关...它与模型挂钩中的gridParas进行调用无关。
  2. 我不清楚get('gridParas')与其余代码的关联位置...但是因为它返回了一个doPost()对象,您可以使用promise允许您基本上等待promise响应,然后在其余代码中使用它。
  3. 简单示例:

    then()

    如果您可以将问题简化为更清晰简洁,我可以提供更多信息

答案 1 :(得分:0)

一般来说,在这个级别你应该解释你想要存档的内容,而不仅仅是问它是如何工作的,因为我认为你在框架中反对很多!

但我从你的评论中删除了这一点。

首先,您不需要使用doPost方法! jQuerys $.ajax返回一个thenable,可以通过Ember.RSVP.resolve解析为Promise!

下一步:如果你想在实际呈现任何内容之前获取数据,你应该在model钩子中执行此操作!

我不确定您是否要抓取/service1,然后通过回复建立对/service2的请求,或者您是否可以独立获取这两项服务然后显示您的数据(你的网格?)与两个服务的数据。所以这两种方式:

如果您可以单独获取这两项服务,请在路由model挂钩中执行此操作:

return Ember.RSVP.hash({
  service1: Ember.RSVP.resolve($.ajax(/*your request to /service1 with all data and params, may use query-params!*/).then(data => {
    return data; // extract the data you need, may transform the response, etc.
  },
  service2: Ember.RSVP.resolve($.ajax(/*your request to /service2 with all data and params, may use query-params!*/).then(data => {
    return data; // extract the data you need, may transform the response, etc.
  },
});

如果您需要/service1的回复来获取/service2,只需在模型钩子中执行此操作:

return Ember.RSVP.resolve($.ajax(/*/service1*/)).then(service1 => {
  return Ember.RSVP.resolve($.ajax(/*/service2*/)).then(service2 => {
    return {
      service1,
      service2
    }; // this object will then be available as `model` on your controller
  });
});

如果这对您没有帮助(我认为这应该可以解决您的问题),请描述您的问题。