Javascript 关于控制器、服务和组件使用的建议

Javascript 关于控制器、服务和组件使用的建议,javascript,ember.js,Javascript,Ember.js,我试图找出如何正确处理控制器和几个组件之间的通信。我想我需要在这里使用服务,但也许另一种解决方案更适合我 这样做的目的是让用户在给出一个问题的情况下得到一个教训。当用户单击“检查”按钮时,应向后端API发出请求,以检查答案是否正确。棘手的是,问题可以有不同的类型:开放式问题、多项选择题和拖放式问题 有一个/lesson/template.hbs,其摘要如下所示: // lesson/template.hbs <h2>{{model.question.lesson.title}}<

我试图找出如何正确处理控制器和几个组件之间的通信。我想我需要在这里使用服务,但也许另一种解决方案更适合我

这样做的目的是让用户在给出一个问题的情况下得到一个教训。当用户单击“检查”按钮时,应向后端API发出请求,以检查答案是否正确。棘手的是,问题可以有不同的类型:开放式问题、多项选择题和拖放式问题

有一个/lesson/template.hbs,其摘要如下所示:

// lesson/template.hbs
<h2>{{model.question.lesson.title}}</h2>

<div class="callout"> {{{model.question.body}}} </div>

{{#if model.question.isMultipleChoice}}
    {{answer-multiple-choice-list answers=model.question.answers}}
{{else if model.question.isDragDrop}}
    {{answer-drag-drop question=model.question}}
{{else if model.question.isOpen}}
    {{answer-open-textarea question=model.question checkAnswer="checkAnswer"}}
{{/if}}

{{#if question_is_answered}}
<a class="next button" {{action 'nextQuestion'}}>Next</a>
{{else}}
<a class="check button" {{action 'checkAnswer'}}>Check</a>
{{/if}}
并有一名服务人员负责粘合控制器和相应部件:

// lesson/service.js
export default Ember.Service.extend({

    is_check_pressed: false,
    has_error: false,

    checkObserver: Ember.observer('is_check_pressed', function() {
        console.log('LessonService: Observer: is_check_pressed changed to', this.get('is_check_pressed'));
    }),

    errorObserver: Ember.on('init', Ember.observer('has_error', function() {
        console.log('LessonService: Observer: has_error changed');
    })),

});
最终,该服务还将包含对后端api的ajax请求

例如,答案开放文本区域组件如下所示:

export default Ember.Component.extend({

    lesson: Ember.inject.service(),
    given_answer: '',

    checkObserver: Ember.on('init', Ember.observer('lesson.is_check_pressed', function() {
        console.log('OpenTextAreaComponent, checkObserver');

        if( Ember.isBlank( this.get('given_answer') ) )
        {
            this.set('lesson.is_check_pressed', false);
            this.set('lesson.has_error', true);
        }
        else
        {
            // Update variable @ service so that the controller knows that the nextQuestion button can be active
        }
    })),

});
验证输入的逻辑应该在组件中,因为对控制器中所有可能的问题类型进行有效性检查是没有意义的

不幸的是,上面的代码没有按它应该的方式工作,即使这只是基本的想法。工作原理是,当按下check按钮时,组件checkObserver在登录到控制台时被激发。但在更新服务中的lesson.has_error时,它不会触发控制器中的errorObserver。而且,即使这可以工作,控制器和组件都将有几个OBE服务器,我觉得这不是一个好的解决方案

我的问题是:控制器和组件如何以正确的方式“通信”?通过使用服务?如果是,那会是什么样子?我想不是通过观察员


提前谢谢

服务被认为是控制器和组件在余烬世界中直接通信的首选(最终也是唯一)方式。然而,我没有发现它们的用途是直观的,所以我只是做了对我有意义的事情

Ember希望您遵循“数据向下,操作向上”的模式。这意味着,如果您希望某个组件中包含任何内容,那么在模板中实例化该组件时,应该将其传递下去。如果希望组件影响控制器,则需要传递操作名称,然后调用sendAction以获得所需的效果

Em.Controller.extend({
  actions: {
    controllerAction: function(){ console.log("you clicked my component"}
  }
})
//template
{{my-component componentAction='controllerAction'}}

Em.Component.extend({
  click: function(){ this.sendAction('componentAction') }
另一种剥猫皮的方法是将控制器向下传递到组件中,并直接对组件中的控制器执行操作

//template 
{{ my-component controller=this }}

这是个骗局,但对我来说很有效。余烬快乐

谢谢您的回复。我想这是一条路,尽管这样通过整个控制器感觉不太对。。不管怎样,它是有效的!
//template 
{{ my-component controller=this }}