从组件更新路由模型
Posted
技术标签:
【中文标题】从组件更新路由模型【英文标题】:Update Route Model from Component 【发布时间】:2017-05-24 20:54:55 【问题描述】:我是 Ember.js 的新手,我正在尝试使用他们的 API 创建一个模仿 Youtube 的应用程序。目前我有一条路线负责从 Youtube Api 获取初始信息以填充加载页面。我有一个搜索栏组件,用于收集用户的输入并使用基于字符串的结果重新填充列表。问题是,当我从用户那里获取输入时,我的 Route 模型没有刷新以从 api 获取更新数据。下面是我的代码。
我的视频路由 video.hbs 的模板:
// app/templates/video.hbs
<div class="row">
search-bar
<div class="row">
<div class="col-md-12">
<hr>
<br>
</div>
</div>
<div class="row">
<div class="col-md-8">
<div class="row">
video-list model=model
<div class="col-md-4 pull-right video-container">
#if videoId
<iframe id="video-player" src="https://www.youtube.com/embed/videoId"></iframe>
else
<iframe id="video-player" src="https://www.youtube.com/embed/kEpOF7vUymc"></iframe>
/if
</div>
</div>
</div>
</div>
</div>
我的搜索栏模板
// app/templates/components/search-bar.hbs
<div class="col-md-12 col-md-offset-4">
<form class="form-inline">
<div class="form-group" onsubmit="return false">
input type="text" class="form-control" value=search id="search" placeholder="Search Videos..."
</div>
<button type="submit" action "updateSearch"class="btn btn-success">Search</button>
</form>
</div>
我的搜索栏组件
// app/components/search-bar.js
import Ember from 'ember';
export default Ember.Component.extend(
userSearch: "",
actions:
updateSearch: function()
this.set("userSearch", this.get("search"));
this.modelFor("videos").reload();
);
视频路线
// app/routes/video.js
import Ember from 'ember';
export default Ember.Route.extend(
model: function()
var userSearch = this.get("search") === undefined ? "Code" : this.get("search");
this.set("search", userSearch);
var url = "https://www.googleapis.com/youtube/v3/search?part=snippet&q="+ userSearch +"&maxResults=50&key="api key goes here";
return Ember.$.getJSON(url).then(function(data)
return data.items.filter(function(vid)
if(vid.id.videoId)
return vid;
);
);
);
【问题讨论】:
【参考方案1】:reload - 不会调用模型钩子方法,在这种情况下,您可以将动作发送到视频路由并从那里尝试refresh。
编辑:
根据您的用例调整您的代码,如果它不起作用或这种方法有什么问题,请告诉我。
app/routes/video.js
这里我们使用 RSVP.hash 函数返回multiple model。我也包括userSearch
。对于这个用例最好实现query parameters,但我没有使用它就实现了。
import Ember from 'ember';
export default Ember.Route.extend(
userSearch: '',
model: function()
var userSearch = this.get("userSearch") === undefined ? "Code" : this.get("userSearch");
var url = "https://www.googleapis.com/youtube/v3/search?part=snippet&q=" + userSearch + "&maxResults=50&key=apikey";
return Ember.RSVP.hash(
videosList: Ember.$.getJSON(url).then(function(data)
return data.items.filter(function(vid)
if (vid.id.videoId)
return vid;
);
),
userSearch: userSearch
);
,
actions:
refreshRoute(userSearch)
this.set('userSearch',userSearch);
this.refresh();
,
);
app/controllers/viedo.js 它包含 refreshRoute 函数,这将调用视频路由文件中可用的 refreshRoute 函数。
import Ember from 'ember';
export default Ember.Controller.extend(
actions:
refreshRoute(userSearch)
this.sendAction('refreshRoute',userSearch);
);
app/templates/video.hbs
1. 我将userSearch
属性和refreshRoute
动作名称传递给搜索栏组件
2. 使用model.videosList
访问videosList
<div class="row">
search-bar userSearch=model.userSearch refreshRoute="refreshRoute"
<div class="row">
<div class="col-md-12">
<hr>
<br>
</div>
</div>
<div class="row">
<div class="col-md-8">
<div class="row">
video-list model=model.videosList
<div class="col-md-4 pull-right video-container">
#if videoId
<iframe id="video-player" src="https://www.youtube.com/embed/videoId"></iframe>
else
<iframe id="video-player" src="https://www.youtube.com/embed/kEpOF7vUymc"></iframe>
/if
</div>
</div>
</div>
</div>
</div>
app/components/search-bar.js
在这里,您将获得 userSearch
属性作为外部属性,即。它将作为包含组件的参数传递。
import Ember from 'ember';
export default Ember.Component.extend(
userSearch:'',//external attributes
actions:
updateSearch()
var userSearch = this.get('userSearch');
this.sendAction('refreshRoute',userSearch); //this will call corresponding controller refreshRoute method
);
app/templates/components/search-bar.hbs
<div class="col-md-12 col-md-offset-4">
<form class="form-inline">
<div class="form-group" onsubmit="return false">
input type="text" class="form-control" value=userSearch id="search" placeholder="Search Videos..."
</div>
<button type="submit" action "updateSearch"class="btn btn-success">Search</button>
</form>
</div>
【讨论】:
我之前尝试过。整个页面将重新加载,用户输入将丢失。 refresh 将触发 beforeModel、model 和 afterModel 钩子。然后数据将在模板中更新。看起来您的代码与search
和 userSearch
属性几乎没有混淆,这可能是用户输入丢失的原因。您可能需要引入 queryParam 进行搜索
我的理解是我从输入中获取值并将该值设置为 userSearch 属性。我的期望是正确的还是我在做不同的事情?
是的,你是对的。那么您是否期望userSearch
可以在routes/video.js
文件中使用?我无法理解模型挂钩中的代码this.set("search", userSearch)
我认为它可以在 routes/video.js 上使用。它会看到发生了变化,然后刷新模型以从 api 获取新结果。我认为“搜索”是全局的,因此可以在模型中设置。以上是关于从组件更新路由模型的主要内容,如果未能解决你的问题,请参考以下文章