gpt4 book ai didi

javascript - 如果模型数据未更改,则防止重新渲染 Ember View

转载 作者:行者123 更新时间:2023-11-29 14:51:56 26 4
gpt4 key购买 nike

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

示例:

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

  • 驯龙高手 (2010)
  • 圣诞怪杰如何偷走圣诞节(2000)
  • 格林奇如何偷走圣诞节! (1966)

如果我添加一个“t”,这样我的查询就变成了“how t”,页面将重新呈现相同的内容,从而造成不必要的数据丢失和相同的闪现数据再次出现:

  • 驯龙高手 (2010)
  • 圣诞怪杰如何偷走圣诞节(2000)
  • 格林奇如何偷走圣诞节! (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;
}
});

最佳答案

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

['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

此外,只是为了好玩,这取决于您的服务器有多快等,您可能希望在用户键入 t 时消除更改请求以减轻一百万个请求,th, the...

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

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

附言尝试降低去抖动率以获得乐趣,看看它在您键入时触发的频率

关于javascript - 如果模型数据未更改,则防止重新渲染 Ember View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24353009/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com