推特路由怎么设置密码(推特位置怎么设置)
「推特路由怎么设置密码(推特位置怎么设置)」是很多朋友的共同疑问。这篇内容从实战角度出发,给出可落地的解决思路。
紧接着Tutorial-弟一部分回顾,继续往super-rental应用添加更有趣的功能。当用户点击列表时可以进入一个详情页面,详情页面可以展示一张更大的地图。
本篇蕞后效果
效果图
本篇学习要点:
在路由中使用动态参数<LinkTo>组件的路由上使用动态参数可以访问路由器的组件测试通过动态参数段访问路由参数在不同的测试用例中共享公共代码在路由中使用动态参数
目前Ember应用的首页列表还是无法点击的,我们可以想象一下,平常在网上冲浪的时候,如果从一个列表点击进入到一个详情页面通常的URL路径是这样的:/列表页面URL/某个数据的id。那么同理rental列表也可以做到,路径是这样的:/rentals/grand-old-mansion。grand-old-mansion就是数据的id。
之所以能接收参数需要修改的路由配置。
ember g route rental
修改路由的默认路径。
import EmberRouter from '@ember/routing/router';import config from './config/environment';export default class Router extends EmberRouter { location = config.locationType; rootURL = config.rootURL;}Router.map { this.route; this.route; this.route;});
注意路由设置路径里面。:rental_id 是一个动态参数,前面是有一个冒号的。这个就是一个动态参数,你可以理解为一个占位符,在访问请求的时候会自动替换成数据的id。
<LinkTo>组件的路由上使用动态参数
修改rental.hbs,在<LinkTo>中传递动态参数。
{{!-- app/components/rental.hbs --}}<article class="rental"> {{!-- 调用Image组件,组件上有两个HTML属性,这两个HTML属性会传递到组件内部的...attributes上 --}} <Rental::Image src={{@rental.image}} alt="A picture of {{@rental.title}}" /> <div class="details"> <h3> {{!-- 添加一个连接,跳转到路由rental上 --}} <LinkTo @route="rental" @model={{@rental}}> {{@rental.title}} </LinkTo> </h3> <div class="detail owner"> <span>Owner:</span> {{@rental.owner}} </div> <div class="detail type"> <span>Type:</span> {{@rental.type}} </div> <div class="detail location"> <span>Location:</span> {{@rental.city}} </div> <div class="detail bedrooms"> <span>Number of bedrooms:</span> {{@rental.bedrooms}} </div> </div> <Map @lat={{@rental.location.lat}} @lng={{@rental.location.lng}} @zoom="9" @width="150" @height="150" alt="A map of {{@rental.title}}" /></article>
主要看这一行
<LinkTo @route="rental" @model={{@rental}}>
在调用LinkTo跳转组件的时候传递了一个@model参数,页面刷新后,鼠标移动到首页图片上,可以看到浏览器底部的状态栏上显示的路径有一个undefine。这是怎么回事呢??
链接上是一个undefined
如果还有印象,前面文章中在路由index.js里面的传递过来的数据是没有包含id属性值的。由于没有id,整个模型就没有id,获取不到自然就是一个空。
修改index.js的取值,增加一个id属性。
// app/routes/index.jsimport Route from '@ember/routing/route';export default class IndexRoute extends Route { // 使用异步方式返回,也就是说,路由一进来之后调用到model方法, // 不会等到model方法执行完毕,它就会先转到模板上。 // 进入本路由的时候就会自动调用这个方法。 async model { // 通过fetch方法调用后端数据 // 更多有关fetch相关的信息请看:https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API let response = await fetch; // 解析数据 // let parsed = await response.json; // return parsed; // 解析JSON数据,获取attributes这个参数里面的数据 let { data } = await response.json; // 通过map函数解析数据。 return data.map) { type = 'Community'; } else { type = 'Standalone'; } return { id, type, ...attributes }; }); }}
注意这两行的改动。
let { id, attributes } = model;return { id, type, ...attributes };
鼠标移动到链接上查看链接地址
修改之后,再看地址状态栏,可以看到是这样的一个地址:http://localhost:4200/rentals/urban-living
点击之后跳转一个空白页面,因为我们还没对这个子路由做任何处理,所以还是一个空白页面。先不急着添加详情页面,先通过测试用例验证新增的链接是否成功了
import { module, test } from 'qunit';import { setupRenderingTest } from 'ember-qunit';import { render } from '@ember/test-helpers';import { hbs } from 'ember-cli-htmlbars';module { setupRenderingTest; test { // Set any properties with this.set; // Handle any actions with this.set { ... }); // 渲染组件,模拟组件的调用等同于在hbs模板中调用<Rental /> // await render; // 使用动态数据之后,需要调整测试用例,此前的测试用例测试的是静态数据, // 先构造一个JSON数据,然后再在调用组件的时候传递过去。 this.setProperties.jpg', description: 'This grand old mansion sits on over 100 acres of rolling hills and dense redwood forests.' } }); // 调用组件时把构造的数据传递过去。 await render; // 断言组件模板的HTML标签 assert.dom.hasClass; assert.dom.hasText; // 断言在rental.hbs添加的详情页面跳转链接 assert.dom.hasAttribute; // 断言这个标签下是否包含文字内容 assert.dom.includesText; assert.dom.includesText; assert.dom.includesText; assert.dom.includesText; assert.dom.exists; // 验证<Map>组件调用成功 assert.dom.exists; });});
注意21行和43行位置,添加了一个id属性,然后断言模板页面上的href属性值。
保存之后,看用例测试结果,but。。。。具体没测试通过。这又是怎么肥四!!!!
对于这种有跳转的路由需要通过代码先关联路由。
在setupRenderingTest;方法之后增加如下3行代码。
hooks.beforeEach { this.owner.setupRouter;});
如果其他测试也发现报错,也需要添加这段代码。
通过动态参数段访问路由参数
增加详情页面处理,现在点击图片上面的链接跳转到的是一个空白页面。首先在路由rental.js增加查询代码,根据动态参数查询某个数据。
// app/routes/rental.jsimport Route from '@ember/routing/route';export default class RentalRoute extends Route { async model { // 获取<LinkTo>上面传递参数,参数的名字就是在router.js里面的定义的动态参数rental_id let response = await fetch; let { data } = await response.json; // 拿到attributes参数 let { id, attributes } = data; // 把数据做一个分类,'Condo','Townhouse','Apartment'归为一类,其他又做了微一类 let type; let community = ['Condo','Townhouse','Apartment']; if ) { type = 'Community'; } else { type = 'Standalone'; } return { id, type, ...attributes }; }}
代码和index路由的很相似,不同的是index获取的是所有数据,rental路由只根据id获取指定的数据。返回的是一条数据。
params.rental_id 这个参数是非常关键的,params是model的入参,这个入参会自动把动态段参数rental_id封装进去。直接获取即可。
详细信息页面
为了展示点击之后的详情页面信息,新增一个子组件用于展示,这个页面会直接展示大图片,和标题。
ember g component rental/detailed
{{!-- app/components/rental/details.hbs 内容和rental模板的基本一致 --}}<Jumbo> <h2>{{@rental.title}}</h2> <p>Nice find! This looks like a nice place to stay near {{@rental.city}}.</p> <a href="#" target="_blank" rel="external nofollow noopener noreferrer" class="share button"> Share on Twitter </a></Jumbo><article class="rental detailed"> <Rental::Image src={{@rental.image}} alt="A picture of {{@rental.title}}" /> <div class="details"> <h3>About {{@rental.title}}</h3> <div class="detail owner"> <span>Owner:</span> {{@rental.owner}} </div> <div class="detail type"> <span>Type:</span> {{@rental.type}} – {{@rental.category}} </div> <div class="detail location"> <span>Location:</span> {{@rental.city}} </div> <div class="detail bedrooms"> <span>Number of bedrooms:</span> {{@rental.bedrooms}} </div> <div class="detail description"> <p>{{@rental.description}}</p> </div> </div> <Map @lat={{@rental.location.lat}} @lng={{@rental.location.lng}} @zoom="12" @width="894" @height="600" alt="A map of {{@rental.title}}" class="large" /></article>
修改app/templates/rental.hbs,在模板中调用新增的子组件detailed,页面刷新后,点击首页列表的标题。
详情页面
效果完美,跳转到一个详情页面,页面上展示一张大图地图,再通过测试用例验证我们的代码。
// tests/acceptance/super-renlats.jsimport { module, test } from 'qunit';import { click, visit, currentURL } from '@ember/test-helpers';import { setupApplicationTest } from 'ember-qunit';module { setupApplicationTest; hooks.beforeEach { this.owner.setupRouter; }); test { // 模拟访问项目,等效于在浏览器输入http://localhost:4200/然后按enter。 await visit; // 相当于进入首页之后,断言当前的URL是/ assert.equal, '/'); // 断言首页是否有h2标签,并且标签里面的内容是Welcome to Super Rentals! assert.dom.hasText; // 通过class属性层级找到按钮 断言按钮的内容是About Us assert.dom.hasText; // 测试导航条 assert.dom.exists; assert.dom.hasText; assert.dom.hasText; // 触发事件,等同于你页面上点击了按钮,然后跳转到about路由下 await click; // 断言是否正确跳转到about路由 assert.equal, '/about'); }); // test { await visit; assert.dom.exists; await click; assert.equal, '/rentals/grand-old-mansion'); }); // 测试详情页, test { await visit; assert.equal, '/rentals/grand-old-mansion'); assert.dom.exists; assert.dom.containsText; assert.dom.containsText; assert.dom.exists; }); // 测试about页面,访问/about路由 test { // 测试进入路由about成功 await visit; // 断言当前的路由是/about assert.equal, '/about'); // 断言h2标签的内容是About Super Rentals assert.dom.hasText; // 测试导航条 assert.dom.exists; assert.dom.hasText; assert.dom.hasText; // 断言有Contact Us按钮 assert.dom.hasText; // 触发点击事件,进入contact路由 await click; // 断言进入contact成功,因为自定义了路由URL,所以要判断当期路径和getting-in-touch是否一致 assert.equal, '/getting-in-touch'); }); // 测试contact页面,访问/getting-in-touch test { await visit; assert.equal, '/getting-in-touch'); assert.dom.hasText; assert.dom.hasText; // 测试导航条 assert.dom.exists; assert.dom.hasText; await click; assert.equal, '/about'); });});
所有测试通过
如果发现还有其他测试无法通过需要修改一些路由文件的的请求URL。
一个是app/routes/index.js,一个是app/routes/rental.js
把里面的URL地址前缀http://location:4200删除。
比如:
let response = await fetch;
改为
let response = await fetch;
查看演示与获取方案
读完本篇后,可通过下方入口查看演示视频、联系客服或访问主站。