AngularJSを使用して簡単なアプリを作成しました。ページを少し開くと、次の画面が表示されます。
ただし、ロードが完了すると、ロードされてスタイル設定されたコンテンツが表示されます。これは問題ありません。
ページでのAngularJSコードのフラッシュを防ぐにはどうすればよいですか?これはFOUCに関連していますか?
HTMLコードは次のとおりです。
<!doctype html>
<html class="no-js" lang="en" ng-app="MainApp">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Foundation | Welcome</title>
<link rel="stylesheet" href="css/foundation.css" />
<script src="js/vendor/modernizr.js"></script>
<style>
.row.full-width {
width: 100%;
margin-left: auto;
margin-right: auto;
max-width: initial;
}
</style>
</head>
<body ng-controller="MainCtrl">
<div class="off-canvas-wrap" data-offcanvas>
<div class="inner-wrap">
<nav class="tab-bar">
<section class="right-small">
<a class="right-off-canvas-toggle menu-icon" href="#"><span></span></a>
</section>
<section class="left tab-bar-section">
<h1 class="title">Salary Calculator</h1>
</section>
</nav>
<aside class="right-off-canvas-menu">
<ul class="off-canvas-list">
<li>
<label>Location</label>
</li>
<li><a href="#">United Kingdom</a>
</li>
</ul>
</aside>
<section class="main-section">
<div class="row full-width">
<div class="large-4 columns">
<ul class="tabs" data-tab>
<li class="tab-title active"><a href="#panel1">Annual Salary</a>
</li>
<li class="tab-title"><a href="#panel2">Monthly Expenses</a>
</li>
</ul>
<div class="tabs-content">
<div class="content active" id="panel1">
<div class="row">
<div class="large-12 columns">
<input ng-change="calculate()" type="text" placeholder="Salary" ng-model="salary"/>
</div>
</div>
</div>
<div class="content" id="panel2">
<div class="row">
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Rent" ng-model="rent" />
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Wireless, TV, Home Phone" ng-model="telecom"/>
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="TV License" ng-model="tv" />
</div>
</div>
<div class="row">
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Mobile Phone" ng-model="mobile"/>
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Subscription" ng-model="subscription"/>
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Electricty" ng-model="electricity" />
</div>
</div>
<div class="row">
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Food" ng-model="food"/>
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Transport" ng-model="transport" />
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Charity" ng-model="charity"/>
</div>
</div>
<div class="row">
<div class="large-12 columns">
<input ng-change="calculate()" type="text" placeholder="Other" ng-model="other"/>
</div>
</div>
</div>
</div>
</div>
<div class="large-8 columns" ng-cloak >
<table >
<thead>
<tr>
<th width="200"></th>
<th width="250">Yearly</th>
<th width="250">Monthly</th>
<th width="250">Weekly</th>
<th width="250">Daily</th>
</tr>
</thead>
<tbody ng-repeat="val in results">
<tr>
<td>{{val.rowType}}</td>
<td>{{val.yearly}}</td>
<td>{{val.monthly}}</td>
<td>{{val.weekly}}</td>
<td>{{val.daily}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<a class="exit-off-canvas"></a>
</div>
</div>
<script src="../bower_components/angularjs/angular.js"></script>
<script src="js/app-service.js"></script>
<script src="js/app-controller.js"></script>
<script src="js/app-directives.js"></script>
<script src="js/app.js"></script>
<script src="js/vendor/jquery.js"></script>
<script src="js/foundation.min.js"></script>
<script>
$(document).foundation();
</script>
</body>
</html>
編集:
受け入れられた解決策に加えて、別の解決策についても 私の答え を参照してください。
ng-cloakはある程度役立ちますが、{{ }}
を使用する代わりにng-bindディレクティブを使用して完全に防ぐことができます。
例えば.
<td ng-bind="val.monthly"> </td>
ない
<td>{{val.monthly}}</td>
久しぶりですが、これが私の実用的なソリューションです。
HTMLのbodyタグでng-cloak
を使用する必要がありますが、最も重要な部分は以下のCSSです。
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display: none !important; }
私にとっては、ng-cloakを機能させるためにこれを追加する必要がありました。他の回答に見られるように、これはおそらくこの問題の唯一の解決策ではありません。これが誰かを助けることを願っています。
_ng-cloak
_とともに、ルーターで_resolve object
_を使用できます。これにより、データがそこにあるまで、コントローラーがインスタンス化され、ビューがレンダリングされなくなります。
次の例では、uiRouter
を使用していると想定しています。同じパターンがngRouter
にも当てはまります。
あなたの状態設定:
_$stateProvider
.state('yourState',{
templateUrl: 'yourTemplate.html',
controller: 'YourController as vm',
resolve: YourController.resolve
})
_
ご覧のとおり、状態のresolveプロパティをコントローラーの静的解決オブジェクトに設定しました。これで、このオブジェクトが解決されるまでルートは解決されません。
解決オブジェクトを設定するために、promiseを返すメソッドyourService
を持つサービスgetData
があると仮定します。これは非常に重要です。なぜなら約束が解決されるまでルートを解決したくない。
したがって、コントローラーは次のようになります。
_YourController.$inject = ['yourService'];
function YourController(yourService) {
var self = this;
yourService.getData().then((data) { self.data = data});
}
_
これはかなり標準的です。 _vm.data
_を使用してビューからデータにアクセスできますが、_{{vm.data}}
_が点滅します。つまり、状態構成に追加した解決策を削除した場合です。
そこで、コントローラーを変更して、状態構成に追加したresolve
で機能する静的解決オブジェクトを追加します。
_YourController.resolve = {
'yourService': 'yourService',
'data': ['yourService', function(yourService) {
return yourService.getData();
}]
}
YourController.$inject = ['data'];
function YourController(data) {
this.data = data;
}
_
これで、resolveオブジェクトができました。 yourService
は通常のサービスとして解決されますが、data
プロパティは、getData()
によって返されたpromiseが解決された場合にのみ解決されます。次に、このdata
は、依存性注入を使用してコントローラーに直接渡されます。
実際には、resolve
を使用する場合は、おそらく_ng-cloak
_を使用する必要はありません。
これが実際の例です:
_angular.module('app', ['ui.router'])
.config(['$stateProvider',
function($stateProvider) {
$stateProvider
.state('noDot', {
controller: "NoDotController",
template: "Using a old style $scope binding {{customers[0].CutomerName}}"
})
.state('noResolve', {
controller: "NoResolveController as vm",
template: "We are displaying things before the data is here {{vm.customers[0].CustomerName}}"
})
.state('withResolve', {
controller: "WithResolveController as vm",
template: "We are waiting for data before displaying anything {{vm.customers[0].CustomerName}}",
resolve: WithResolveController.resolve
})
.state('empty', {
template: ""
})
}
])
.controller('NoResolveController', NoResolveController)
.controller('NoDotController', NoDotController)
.controller('WithResolveController', WithResolveController)
.service('northwind', Northwind);
NoDotController.$inject = ['$scope', 'northwind'];
function NoDotController($scope, northwind) {
northwind.getCustomers().then(function(customers) {
$scope.customers = customers});
}
NoResolveController.$inject = ['northwind'];
function NoResolveController(northwind) {
var self = this;
northwind.getCustomers().then(function(customers) {
self.customers = customers;
});
}
WithResolveController.resolve = {
'northwind': 'northwind',
'customers': ['northwind',
function(northwind) {
return northwind.getCustomers();
}
]
}
WithResolveController.$inject = ['customers'];
function WithResolveController(customers) {
this.customers = customers;
}
Northwind.$inject = ['$timeout', '$q'];
function Northwind($timeout, $q) {
this.$q = $q;
this.$timeout = $timeout;
}
Northwind.prototype.getCustomers = function() {
var deferred = this.$q.defer();
this.$timeout(function() {
deferred.resolve([{CustomerName: "Name of Customer"}])
}, 1000);
return deferred.promise;
}
_
_<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.13/angular-ui-router.js"></script>
<div ng-app="app">
<a ui-sref="noDot" href="#">No Dot</a>
<span> | </span>
<a ui-sref="empty" href="#">Emtpy</a>
<span> | </span>
<a ui-sref="noResolve" href="#">No Resolve</a>
<span> | </span>
<a ui-sref="empty" href="#">Emtpy</a>
<span> | </span>
<a ui-sref="withResolve" href="#">With Resolve</a>
<br>
<br>
<ui-view></ui-view>
</div>
_
Angularはすでにこれを防ぐためのツールを提供しています:ngCloak
: https://docs.angularjs.org/api/ng/directive/ngCloak
<body ng-cloak>
のようにディレクティブを体に置くだけで、機能するはずです。
[〜#〜] edit [〜#〜]ドキュメントは、実際には本文ではなく、ページの小さな部分に配置するようにアドバイスしています。 -必要があればどこでも。ページのサイズにもよりますが、それは良い考えです。小さいページの場合は、本文に配置しましたが、問題は発生しませんでした。