2

我试图了解这是否是在这里做事的最佳方式,因为对我来说它看起来像代码味道。我想要做的是,当我单击它时,我的按钮会变为加载状态,当控制器结束处理事件时它会变回默认状态(基本上是进行 AJAX 调用)

我的模板如下所示:

{{#view App.LoadingButton action="search" data-loading-text="content.loadingText"}}Search{{/view}}

我的观点是这样的:

App.LoadingButton = Ember.View.extend({
    tagName: 'button',
    classNames: ['btn', 'btn-primary'],
    attributeBindings: ['type'],
    type: 'button',
    elem: null,
    stateChanged: function () {
        if (this.elem) {
            var loading = this.get('controller').get('content.isLoading');
            if (loading) {
                $(this.elem).button('loading');
            }
            else {
                $(this.elem).button('reset');
            }            
        }        
    },
    click: function (evt) {
        this.elem = this.elem || evt.srcElement;
        this.get('controller').send(this.get('action'));
    },
    didInsertElement: function () {
        this.get('controller').addObserver('content.isLoading', this, 'stateChanged');
    }
});
  1. 首先,我访问我的元素的方式看起来是错误的,当它被添加到 DOM 时,我不能获得对我的视图元素的引用吗?
  2. 其次,我依靠控制器从其模型中更改 isLoading 布尔标志,以便视图知道何时更改状态,这是以 Ember 方式实现它的最佳方式吗?

我看过很多关于 Ember 的视频,刚开始用它来实现,但要知道什么是最好的方法仍然不是一件容易的事,即使它可能像这样工作。

4

1 回答 1

4

我想要做的是,当我单击它时,我的按钮会变为加载状态,当控制器结束处理事件(基本上是进行 AJAX 调用)时,它会变回默认状态。

您正在描述 Ember 帮助人们摆脱的以文档/事件为中心的架构(具有紧密的显示/交互耦合)。Ember 更多地描述了应用程序的数据状态以及显示在每种状态下的显示方式。Ember 本身会为您处理要显示的数据同步。

一种更像 Ember 的描述方式是:

  • 显示行为
    • 当我与服务器通信时,该按钮有一个disabled类并显示“正在加载...”
    • 当我不与服务器通信时,按钮没有disabled显示“搜索”的类
    • 交互时,此按钮会触发搜索动作

模板:

<button type="button" 
        {{bindAttr class=":btn :btn-primary isLoading:disabled"}} 
        {{action search}}>
  {{#if isLoading}}
    Loading...
  {{else}}
    Search
  {{/if}}
</button>
  • 流量控制行为
    • 触发搜索时,控制器isLoading变为真
    • 搜索完成后,控制器的isLoading属性变为 false
    • 如果搜索已经在进行中,则忽略再次搜索的尝试

控制器:

App.SomeController = Ember.Controller.extend({
  isLoading: false,
  search: function(){
    if(this.get('isLoading')) { return }

    this.set('isLoading', true);
    $.ajax({
      context: this,
      success: function(){
        this.set('isLoading', false)
      }
    })
  }
});
于 2013-03-16T18:03:53.580 回答