【问题标题】:Ember.js - How can I bind a property of a model class to a controller?Ember.js - 如何将模型类的属性绑定到控制器?
【发布时间】:2013-04-03 17:56:45
【问题描述】:

我正在尝试以某种方式将以下模型的属性绑定到控制器,以便在模型完成其异步调用时设置模型的长度属性,然后通知控制器更改并可以更新看法。

App.Articles = Ember.Object.extend()

App.Articles.reopenClass
    store: {}
    lengths: 0

    findAll: ->
        arr = Ember.ArrayProxy.create()

        $.ajax
            url: 'http://ajaxcall.asp',
            dataType: 'json'
            context: @
            success: (response) ->
                Ember.set(App.Articles, 'lengths', response.store.length)

                response.store.forEach (news, i) =>
                    txt = '<p>' + news.fields[2].text.replace(/[\r\n]+(?=[^\r\n])/g,'</p><p>') + '</p>'
                    article = 
                        'id': i
                        'date': news.fields[1].date
                        'title': news.fields[0].text
                        'text': txt
                        'short': news.fields[2].text.substring(0, 120) + '...'

                    art = @findOne(article.id)
                    art.setProperties(article)
                    return

                values = (values for keys, values of @store)
                arr.set('content', values)

                callback = ->
                    $('.loader-container').removeClass('show')
                    $('#articles-scroll').css('height', $(window).height() - 55)

                    articles_scroll = new iScroll 'articles-scroll', 
                        vScroll: true, hScroll: false, vScrollbar: false
                    return

                setTimeout callback, 100
                return
        arr

    findOne: (id) ->
        art = @store[id]
        if not art
            art = App.Currencies.create
                id: id
            @store[id] = art
        art     

所以我需要完成的是设置调用完成后返回的数据的长度,并在控制器中监听该更改,如下所示:

lengths: (->
    console.log 'test'
).property('App.Articles.lengths')

但是,我对上面的代码不满意,我不知道如何解决这个问题。

【问题讨论】:

    标签: javascript model-view-controller asynchronous ember.js coffeescript


    【解决方案1】:

    如果您想在模板中使用该值,只需使用控制器的长度属性:{{controller.length}}。

    如果要观察控制器中的长度属性:

    App.ArticlesController = Ember.ArrayController.extend({
      lengthDidChange: function() {
        console.log("Length changed to: " + this.get('length'));
      }.observes('length')
    });
    

    如果您在路由的 model 钩子或其他地方设置了带有文章数组的控制器。

    更新:

    如果您想要一次性通知,请将Ember.Evented 混入您从findAll 返回的ArrayProxy(省略不需要的内容):

    App.Articles.reopenClass
      ...
      findAll: ->
        arr = Ember.ArrayProxy.createWithMixins(Ember.Evented)
    
        $.ajax
          ...
          success: (response) ->
            ...
            arr.set('content', values)
            arr.trigger('didLoad')
    
    App.ArticlesRoute = Ember.Route.extend
      model: ->
        App.Articles.findAll()
    
      setupController: (controller, model)->
        model.one 'didLoad', ->
          console.log controller.get('lastObject`)
    

    【讨论】:

    • 加博尔,感谢您的回复。我不需要监控每一个变化——我只需要在调用完成后设置一个特定的文章。如果我观察到长度变化,我将在每次更改时设置一篇文章,而我只需要在它们全部加载后设置一篇文章。有什么想法吗?
    • 你能再解释一下“我只需要设置一个特定的文章”吗?
    • Gabor - 感谢您回复我。因此,该页面正在左侧加载文章列表,我想在页面首次加载时使用列表中的一篇文章的详细信息填充右侧。我想使用传入数据中的最后一篇文章(因为那是最近的文章)我遇到的问题是我需要等待数据完全加载才能知道有多少文章进来并可以选择最后一个。但我不知道如何让模型以某种方式通知控制器调用已完成并且它现在有 x 篇文章。
    • 控制器的lastObject 属性将始终代表最后一个元素。
    • Gabor - 但是我如何等到模型完全填充后才能获得最后一个对象?有没有办法让模型通知已完成 ajax 调用的控制器?
    猜你喜欢
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-12
    • 2017-05-13
    相关资源
    最近更新 更多