如果模型数据没有改变,则防止重新渲染Ember视图

时间:2014-06-22 16:00:18

标签: javascript ember.js ember-data

我正在尝试创建一个自动完成功能,该功能从Trakt API获取电影并将前3个结果呈现在页面上。每次更改“查询”文本(来自输入)时,我都会获得新数据。但是,即使这3个型号保持不变, Ember也会重新呈现页面。如何防止这种情况发生?有没有办法添加某种检查,以查看在Handlebars模板中movie.title和movie.year是否不同?或者在控制器内进行检查,只有在不同的情况下才会设置新模型?

实施例

如果我输入“how”作为我的查询,该页面将呈现:

  • 如何训练你的龙(2010)
  • Grinch如何偷圣诞节(2000)
  • Grinch如何偷走圣诞节! (1966)

如果我添加't',以便我的查询变为“how t”,页面将重新呈现相同的内容,从而创建不必要的数据闪存并且相同数据再次出现:

  • 如何训练你的龙(2010)
  • Grinch如何偷圣诞节(2000)
  • Grinch如何偷走圣诞节! (1966)

代码:

HTML

<script type="text/x-handlebars" data-template-name="application">
    <div class="hero-unit">
    <h1>App</h1>
    {{outlet}}
    </div>
</script>
<script type="text/x-handlebars" data-template-name="index">
    {{input value=query}}
    <div class="prompt">
      {{prompt}}
    </div>

    {{#if moviesAvailable}}
      {{#each movie in movies}}
        <li>{{movie.title}} ({{movie.year}})</li>
      {{/each}}
    {{/if}}
</script>

Javascript(IndexController中“查询”的更改会触发MovieController中“查询”的更改,提示它设置新模型)

var App;

App = Ember.Application.create();

App.Movie = DS.Model.extend({
  title: DS.attr('string'),
  year: DS.attr('number'),
  fanart: DS.attr('string'),
  poster: DS.attr('string'),
  overview: DS.attr('string')
});

App.IndexController = Ember.ArrayController.extend({
  needs: "movies",
  movies: Ember.computed.alias("controllers.movies"),
  query: '',
  prompt: '',
  moviesAvailable: false,
  queryChanged: (function() {
    var length;
    length = this.get('query').length;
    if (length === 0) {
      this.set('moviesAvailable', false);
      return this.set('prompt', 'Please type two more characters.');
    } else if (length === 1) {
      this.set('moviesAvailable', false);
      return this.set('prompt', 'Please type one more character.');
    } else {
      this.set('moviesAvailable', true);
      this.set('prompt', '');
      return this.get('movies').set('query', this.get('query'));
    }
  }).observes('query')
});

App.MoviesController = Ember.ArrayController.extend({
  queryChanged: (function() {
    var newmodel;
    newmodel = this.store.find('movie', {
      query: this.get('query'),
      limit: 3
    });
    return this.set('model', newmodel);
  }).observes('query')
});


App.MovieAdapter = DS.RESTAdapter.extend({
  host: 'http://api.trakt.tv/search/movies.json',
  namespace: '5aa5a25cfc06d869c136725b2b29d645',
  ajaxOptions: function(url, type, hash) {
    hash = this._super(url, type, hash);
    hash.dataType = 'jsonp';
    return hash;
  }
});

App.MovieSerializer = DS.RESTSerializer.extend({
  normalizeHash: {
    movie: function(hash) {
      hash.id = hash.tmdb_id;
      hash.fanart = hash.images.fanart;
      hash.poster = hash.images.poster;
      delete hash.images;
      return hash;
    }
  },
  normalizePayload: function(payload) {
    var json;
    json = {
      "movie": payload
    };
    return json;
  }
});

1 个答案:

答案 0 :(得分:2)

问题是它们是类似的结果,但不是相同的集合。

['a', 'b', 'c'] === ['a', 'b', 'c']是假的。它们是两个不同的集合,可能包含相同的值,看起来相似,但它们是不同的实例等。

示例:http://emberjs.jsbin.com/OxIDiVU/698/edit

如果您愿意,您可以滚动自己的集合,并手动更新记录,这样可以避免整个集合消失,并在它们是相同的项目时重新出现。但是当它们不同时,它仍然会被破坏。

  watchInput: function(){
    //model here is just an []
    var model = this.get('model');

    this.store.find('color', {
      limit:10
    }).then(function(results){
      var len = results.get('length'),
          curItem,
          newItem;

      for(var i = 0;i<len;i++){
        curItem = model.objectAt(i);
        newItem = results.objectAt(i);
        if(curItem!=newItem){
          if(!curItem){
            model.pushObject(newItem);
          } else{
            model.replace(i,1,[newItem]);
          }

        }
      }
      // maybe remove additional items if it only returns 1, or 2 or even 0 for that matter.
    })
  }.observes('stuff'),

示例:http://emberjs.jsbin.com/OxIDiVU/697/edit

另外,只是为了它的乐趣,取决于您的服务器的速度等,您可能希望在用户输入tth时撤消更改请求以减少一百万个请求,the ......

watchInput: function(){
    Ember.run.debounce(this, this.slowFetch, 400);
  }.observes('stuff'),

http://emberjs.jsbin.com/OxIDiVU/721/edit

P.S。尝试降低去抖率以获得乐趣,看看当你输入

时它的频率