几个月前,我创建了一个主题:Try to render two templates in same View (Ui-Router),在那里我询问了如何在同一页面中渲染多个视图。我的目标是创建一个 Web 应用程序作为桌面应用程序,具有最小化、最大化、关闭等类似的视图。
好吧,我的应用程序已准备就绪,但我遇到了问题,当我将应用程序投入生产时,一些计算机需要很长时间才能呈现所有视图。在下面的图片中,我们可以看到很多服务器用来返回我的模板 URL 的请求。
有没有办法避免这种情况?我正在寻找对 templateURL 的延迟加载,但我没有找到。:(
这个 plunkr 是我使用的方法。我的所有视图只有一种状态(我当前的 app.config 有 103 个视图):
routerApp.config(function($stateProvider) {
$stateProvider.state('mainState', {
views: {
'CompanyView': {
templateUrl: 'Company.html'
},
'PeopleView': {
templateUrl: 'People.html'
},
.....
....
}
})
});
您接近解决方案的方式是您面临的问题的原因,因为对于单个状态您有太多视图,最终必须加载所有视图以设置该状态,所以每次您访问您的状态,ui-router
必须加载每个模板才能设置视图。对于少数几个模板,它可能不会引起问题,但是,对于像您这样的较大数量的模板,这绝对是一个问题。
您可以尝试在您的页面中缓存您的模板<script type="text/ng-template"...
以防止加载时间,顺便说一句,这是一个很好的做法。通常它是生产构建优化的一部分,加载模板缓存中的所有模板,以便应用程序加载时间显着减少,前提是您不必等待 http 调用来加载页面。它确实会提高您的情况的性能,但我没有一个基准来确保它是否足以满足您的情况。
无论如何,您始终可以实现界面组件以按照您想要的方式运行,并以无需加载一百个模板来为用户显示单个面板的方式进行优化。
我的建议是,不要使用 ,而是使用ui-router
基于组件的解决方案,创建一个指令组件来保存每个窗口的面板内容及其行为;并使用控制器管理打开和关闭面板的状态,在列表中保存和管理每个打开的面板等。例如:
<nav>
<button ng-click="openPanel({title: 'My Panel Title', templateUrl: 'myPanel.html'>">
Open myPanel
</button>
<nav>
<main>
<panel ng-repeat="panel in openedPanels"></panel>
</main>
下面的代码片段使用 bootstrap 4 css 实现了这种方法,每个面板都是一个引导卡,它有一个可以打开的面板列表,点击导航列表时,它将相应的面板添加到打开的面板列表中,angularjs 可以在其中渲染它在 html 上使用ng-repeat
. 这样,只会渲染打开的窗口,因此只会加载打开的窗口模板。
免责声明:这是一个非常简单的示例,未使用可用的最佳实践实现。如果您打算使用这种方法,您应该根据您的应用程序来实现它以更好地适应您的体系结构的需求,这不是一个完整的功能组件,它只是为了演示的一个示例。
angular.module('app', [])
.controller('PanelsCtrl', function($scope) {
// available windows to be opened
$scope.panels = [
{ title: 'Window 1', templateUrl: 'window1.html' },
{ title: 'Window 2', templateUrl: 'window2.html' }];
// all currently opened panels
$scope.openedPanels = [];
// opens a panel (a.k.a, adds a panel
// to the opened panels list)
$scope.openPanel = function(panel) {
if ($scope.openedPanels.indexOf(panel) === -1)
$scope.openedPanels.push(panel);
};
// close a panel (a.k.a, removes a panel
// from the opened panels list)
$scope.onClosePanel = function(panel) {
$scope.openedPanels.splice($scope.openedPanels.indexOf(panel), 1);
};
})
.directive('window', function($templateRequest, $templateCache, $compile) {
return {
restrict: 'E',
scope: {
panel: '=',
onClosePanel: '&'
},
template: `
<div class="card">
<h4 class="card-header">
<span>{{ panel.title }}</span>
<button
ng-click="onClosePanel(panel)"
type="button"
class="close"
data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</h4>
<div class="card-body">
<ng-include src="panel.templateUrl"></ng-include>
</div>
</div>
`
}
})
// example controlelr to be used with ng-controller
.controller('Window1Ctrl', function($scope) {
$scope.window1Prop = 'This is a property from Window1Ctrl'
})
@import 'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css'
<div ng-app="app">
<div class="container" ng-controller="PanelsCtrl">
<div class="row">
<div class="col-sm-3">
<ul class="nav flex-column">
<li class="nav-item" ng-repeat="panel in panels">
<a class="nav-link active" href="#" ng-click="openPanel(panel)">
{{ panel.title }}
</a>
</li>
</ul>
</div>
<div class="col-sm-9">
<window ng-repeat="panel in openedPanels" panel="panel" on-close-panel="onClosePanel(panel)">
</window>
</div>
</div>
</div>
<!-- NG-TEMPLATES -->
<script type="text/ng-template" id="window1.html">
<div ng-controller="Window1Ctrl">
<b>{{panel.title}}</b>
<h5>window1Prop: {{ window1Prop }}</p>
</div>
</script>
<script type="text/ng-template" id="window2.html">
<em>{{panel.title}}</em>
</script>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.js"></script>
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句