Angular SPAは、さまざまなおすすめリストを表示し、いくつかのレストランデータの異なるカットに基づいて場所のGoogleマップを表示します( m.amsterdamfoodie.nl =)。これらの各リストに独自のURLを持たせたいGoogleが異なるリストをクロールできるようにするために、offcanvasナビゲーションに_<a>
_タグを使用します。
現在、_<a>
_タグによりビューが更新されますが、これはマップで非常に顕著です。
ng-click
_および$event.preventDefault()
を使用してこれを防ぐことができます(以下のコードスニペットを参照)が、ブラウザーのURLを更新する手段を実装する必要があります。$state
_またはブラウザの_history.pushstate
_を試してみると、状態の変更がトリガーされ、ビューが更新されます...!したがって、私の質問はモデルとURLを更新できますが、ビューを更新せずにどうすればよいですか?( Angular/UI-Routerも参照してください-すべてを更新せずにURLを更新するにはどうすればよいですか? )
私は多くのアプローチを試し、現在このhtmlを持っています
_<a href="criteria/price/1" class="btn btn-default" ng-click="main.action($event)">Budget</a>
_
コントローラー内:
_this.action = ($event) ->
$event.preventDefault()
params = $event.target.href.match(/criteria\/(.*)\/(.*)$/)
# seems to cause a view refresh
# history.pushState({}, "page 2", "criteria/"+params[1]+"/"+params[2]);
# seems to cause a view refresh
# $state.transitionTo 'criteria', {criteria:params[1], q:params[2]}, {inherit:false}
updateModel(...)
_
そして、私が起こっていると思うことは、_$stateProvider
_コードをトリガーしていることです:
_angular.module 'afmnewApp'
.config ($stateProvider) ->
$stateProvider
.state 'main',
url: '/'
templateUrl: 'app/main/main.html'
controller: 'MainCtrl'
controllerAs: 'main'
.state 'criteria',
url: '/criteria/:criteria/:q'
templateUrl: 'app/main/main.html'
controller: 'MainCtrl'
controllerAs: 'main'
_
考えられる手がかりの1つは、以下のコードを使用して、たとえば http://afmnew.herokuapp.com/criteria/cuisine/italian ナビゲートするとビューが更新されますが、ロードすると http://afmnew.herokuapp.com/ =更新はありませんが、代わりにURLの更新はありません。なぜそれが起こっているのか全く分かりません。
以前の議論に基づいて、UI-Router
ここに。私はあなたの挑戦を正しく理解していると信じています... 実例 があります。これが完全にスイートではない場合、いくつかのインスピレーションとして受け取ってください
免責事項:配管工では、これを達成できませんでした: http://m.amsterdamfoodie.nl/ 、しかし、原則はその中にあるべきです 例 類似
したがって、状態の定義があります(2つの状態しかありません)
$stateProvider
.state('main', {
url: '/',
views: {
'@' : {
templateUrl: 'tpl.layout.html',
controller: 'MainCtrl',
},
'right@main' : { templateUrl: 'tpl.right.html',},
'map@main' : {
templateUrl: 'tpl.map.html',
controller: 'MapCtrl',
},
'list@main' : {
templateUrl: 'tpl.list.html',
controller: 'ListCtrl',
},
},
})
.state('main.criteria', {
url: '^/criteria/:criteria/:value',
views: {
'map' : {
templateUrl: 'tpl.map.html',
controller: 'MapCtrl',
},
'list' : {
templateUrl: 'tpl.list.html',
controller: 'ListCtrl',
},
},
})
}];
これがメインtpl.layout.html
<div>
<section class="main">
<section class="map">
<div ui-view="map"></div>
</section>
<section class="list">
<div ui-view="list"></div>
</section>
</section>
<section class="right">
<div ui-view="right"></div>
</section>
</div>
ご覧のとおり、メイン状態は、メイン状態のこれらのネストされたビューをターゲットにしています: 'viewName @ main'、例: 'right@main'
サブビュー、main.criteria
はlayoutビューに挿入します。
そのURLは記号で始まります^(url : '^/criteria/:criteria/:value'
)、/
スラッシュはメインのスラッシュであり、子のダブルスラッシュではありません
また、コントローラーもありますが、ここでは少し素朴ですが、背景には実際のデータ負荷(基準に基づく)が存在する可能性があることを示しているはずです。
ここで最も重要なのは、親MainCtrl
が$scope.Model = {}
。このプロパティは(継承のおかげで)親と子の間で共有されます。これがすべてが機能する理由です:
app.controller('MainCtrl', function($scope)
{
$scope.Model = {};
$scope.Model.data = ['Rest1', 'Rest2', 'Rest3', 'Rest4', 'Rest5'];
$scope.Model.randOrd = function (){ return (Math.round(Math.random())-0.5); };
})
.controller('ListCtrl', function($scope, $stateParams)
{
$scope.Model.list = []
$scope.Model.data
.sort( $scope.Model.randOrd )
.forEach(function(i) {$scope.Model.list.Push(i + " - " + $stateParams.value || "root")})
$scope.Model.selected = $scope.Model.list[0];
$scope.Model.select = function(index){
$scope.Model.selected = $scope.Model.list[index];
}
})
これにより、UI-Routerが提供する機能をどのように使用できるかがわかります。
拡張:新しいプランカー ここ
マップビューを再作成したくない場合は、子状態defからそのフォームを省略できます。
.state('main.criteria', {
url: '^/criteria/:criteria/:value',
views: {
// 'map' : {
// templateUrl: 'tpl.map.html',
// controller: 'MapCtrl',
//},
'list' : {
templateUrl: 'tpl.list.html',
controller: 'ListCtrl',
},
},
})
これで、マップVIEWはモデルの変更を受信するだけになります(監視することができます)が、ビューとコントローラーは再レンダリングされません
また、別のプランカーがあります http://plnkr.co/edit/y0GzHv?p=previewcontrollerAs
を使用します
.state('main', {
url: '/',
views: {
'@' : {
templateUrl: 'tpl.layout.html',
controller: 'MainCtrl',
controllerAs: 'main', // here
},
...
},
})
.state('main.criteria', {
url: '^/criteria/:criteria/:value',
views: {
'list' : {
templateUrl: 'tpl.list.html',
controller: 'ListCtrl',
controllerAs: 'list', // here
},
},
})
それは次のように使用できます:
<h4>{{main.hello()}}</h4>
<h4>{{list.hello()}}</h4>
最後のプランカーは ここ です
これは、私が正しく理解している場合の道の例です。
$state.go('my.state', {id:data.id}, {notify:false, reload:false});
//And to remove the id from the url:
$state.go('my.state', {id:undefined}, {notify:false, reload:false});
問題のユーザーl-liava-lから https://github.com/angular-ui/ui-router/issues/ 64
$state
ここにAPI: http://angular-ui.github.io/ui-router/site/#/api/ui.router.state 。$ state
スコープの継承を使用して、ビューを更新せずにURLを更新できます
$stateProvider
.state('itemList', {
url: '/itemlist',
templateUrl: 'Scripts/app/item/ItemListTemplate.html',
controller: 'ItemListController as itemList'
//abstract: true //abstract maybe?
}).state('itemList.itemDetail', {
url: '/:itemName/:itemID',
templateUrl: 'Scripts/app/item/ItemDetailTemplate.html',
controller: 'ItemDetailController as itemDetail',
resolve: {
'CurrentItemID': ['$stateParams',function ($stateParams) {
return $stateParams['itemID'];
}]
}
})
子ビューが親ビュー内にある場合、両方のコントローラーが同じスコープを共有します。そのため、ダミー(または必要な)ui-viewを親ビュー内に配置して、子ビューに取り込むことができます。
を挿入します
$scope.loadChildData = function(itemID){..blabla..};
コントローラーのロード時に子コントローラーによって呼び出される親コントローラーの関数。ユーザーがクリックしたとき
<a ui-sref="childState({itemID: 12})">bla</a>
子コントローラーと子ビューのみが更新されます。次に、必要なパラメーターを指定して親スコープ関数を呼び出すことができます。
簡単な答えは、do notになってしまい、変更するビュー内にマップを配置しました。受け入れられた答えは、サブビューでページを構成する方法についてより多くの詳細を提供しますが、キーポイントはマップをビューの一部にするのではなく、その動作を変更するビューに接続し、コントローラを使用して市場のアイコンを更新します。