Angular 2:检测浏览器宽度的变化并更新模型
Posted
技术标签:
【中文标题】Angular 2:检测浏览器宽度的变化并更新模型【英文标题】:Angular 2: Detect changes in browser width and update model 【发布时间】:2017-01-25 19:17:46 【问题描述】:在我的Angular 2
应用程序中,我根据浏览器窗口宽度更改样式。这是一个示例(SCSS):
.content
/*styles for narrow screens*/
@media (max-width: 750px)
background-color:beige;
/*styles for medium screens*/
@media (min-width: 751px) and (max-width: 1200px)
background-color:red;
/*styles for wide screens*/
@media (min-width: 1201px)
background-color:brown;
这使我的 UI 具有响应性。我希望我的 Angular 组件知道当前的宽度间隔:
/* Returns which of the CSS width intervals is current*/
getWidthRange()
let pixelWidth = ...; //what goes here?
if(pixelWidth < 251) return "small";
if(pixelWidth < 451) return "medium";
return "large";
组件会调用此函数并根据宽度调整其行为。例如,下面的模板将在更宽的屏幕上显示更多内容:
<div>
getWidthRange()==='small'? shortText : longText
</div>
更好的是,我会设置一个 Observable,它会在浏览器从一个范围转换到下一个范围时发出:
widthRangeChanges = Observable.create( observer =>
// ? how to detect when width changes
let oldRange = '...';
let newRange = '...';
if(newRange!==oldRange) observer.next(newRange);
).share(); //all subscribers share same output channel
然后组件可以订阅widthRangeChanges
并在收到新范围时更新模型值。我如何在Angular 2
中获取此信息?
Angular 2 rc-6
、typescript 2.0.2
、rxjs 5 beta 11
【问题讨论】:
【参考方案1】:你可以使用RxJS的fromEvent
操作符:
const $resizeEvent = Observable.fromEvent(window, 'resize')
.map(() =>
return document.documentElement.clientWidth;
)
.debounceTime(200)
$resizeEvent.subscribe(data =>
this.width = data;
);
Plunker Example
【讨论】:
感谢您的提示。我不知道fromEvent
。这些事件是 RxJS 专有的,还是我可以通过这种方式将任何 JS 事件转换为 Observable?
我猜它只适用于 DOM 事件
这是一个很棒的提示,Plunker 也是如此。我会试试看。这是一个使答案更有帮助的链接:reactivex.io/rxjs/class/es6/…
我使用了您的解决方案。不过没有必要使用map
。 fromEvent
可以接受第三个参数,一个返回您希望 Observable 发出的内容的函数。请参阅plnkr.co/edit/lgkRt8nNMScPOH7QmrBS?p=preview
谢谢,非常优雅的解决方案!只有一件事:在现代 Angular 版本中,您应该使用这种方法导入 fromEvent、map 和 debounceTime:***.com/questions/50571550/…【参考方案2】:
模板
<div (window:resize)="onResize($event)"></div>
export class AppComponent
onResize(event)
console.log(event);
console.log("width:" + event.target.innerWidth);
console.log("height:" + event.target.innerHeight);
this.pixelWidth = event.target.innerWidth;
getWidthRange()
if(this.pixelWidth < 251) return "small";
if(this.pixelWidth < 451) return "medium";
return "large";
【讨论】:
我从未见过这种(window:resize)
事件绑定表示法。这是标准Angular 2
吗? (任何指向官方文档的链接都会有所帮助)
我曾在某处阅读过其中一个 beta 版本(现在我不记得参考了)。后来在我的项目中实现。我猜文档还没有。【参考方案3】:
getWidth()
return Math.max(
document.body.scrollWidth,
document.documentElement.scrollWidth,
document.body.offsetWidth,
document.documentElement.offsetWidth,
document.documentElement.clientWidth
);
【讨论】:
请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助,质量更高,更有可能吸引投票。以上是关于Angular 2:检测浏览器宽度的变化并更新模型的主要内容,如果未能解决你的问题,请参考以下文章