Home - kotazi/ui-router GitHub Wiki
Next (Nested States & Nested Views) ►
This In-Depth Guide will take you through all aspects of the UI-Router and its components and options. If you just need a quick reference guide visit the API Reference
The new $stateProvider works similar to Angular's v1 router, but it focuses purely on state.
- A state corresponds to a "place" in the application in terms of the overall UI and navigation.
- A state describes (via the controller / template / view properties) what the UI looks like and does at that place.
- States often have things in common, and the primary way of factoring out these commonalities in this model is via the state hierarchy, i.e. parent/child states aka nested states.
新しい$stateProviderはAngular v1のルーターに似ていますが、あくまでもステートに焦点を当てています。
- ステートは、全体的なUIとナビゲーションの面でアプリケーション内の「場所」に相当します。
- ステートは(コントローラーやテンプレート、ビュープロパティを通して)、UIの見え方や場所について述べます。
- ステートは多くの場合、共通のものを持っており、このモデルの共通部分を外に出す主要な方法はステートヒエラルキーと通すことです。(親と子がネストされた状態)(謎)
A state in its simplest form can be added like this (typically within module.config):
ステートの最もシンプルな形はこのようになっています。
<!-- in index.html -->
<body ng-controller="MainCtrl">
<section ui-view></section>
</body>
// in app-states.js (or whatever you want to name it)
$stateProvider.state('contacts', {
template: '<h1>My Contacts</h1>'
})
When a state is activated, its templates are automatically inserted into the ui-view
of its parent state's template. If it's a top-level state—which 'contacts' is because it has no parent state–then its parent template is index.html.
ステートがアクティブの時、そのステートのテンプレートは自動的に、親ステートのテンプレートのui-view
内に挿入されます。もしそれがトップレベルのステートであれば、例えばcontacts
には親のステートがないので、index.html
が親のテンプレートになります。
Right now, the 'contacts' state won't ever be activated. So let's see how we can activate a state.
今、contacts
はアクティブになりません。ではどうすればアクティブにできるか見ていきましょう。
There are three main ways to activate a state:
- Call
$state.go()
. High-level convenience method. Learn More - Click a link containing the
ui-sref
directive. Learn More - Navigate to the
url
associated with the state. Learn More.
ステートをアクティブにする3つの方法。
-
#state.go()
を呼ぶ。かなり便利なメソッドです。詳しくはこちら。 -
ui-sref
を含んだディレクティブをクリック。詳しくはこちら。 - ステートに関連した
url
へ行く。詳しくはこちら。
There are several methods for configuring a state's template.
ステートのテンプレートを設定するいくつかのメソッドがあります。
As seen above, the simplest way to set your template is via the template
config property.
上のシンプルな例ではtemplate
プロパティを使いました。
$stateProvider.state('contacts', {
template: '<h1>My Contacts</h1>'
})
Instead of writing the template inline you can load a partial. (This is probably how you'll set templates most of the time.)
テンプレートを書く代わりにパーティクルを読ませることができます。(多分もっとも使うでしょう。)
$stateProvider.state('contacts', {
templateUrl: 'contacts.html'
})
templateUrl
can also be a function that returns a url. It takes one preset parameter, stateParams, which is not injected.
templateUrl
はurlを返す関数でもいいです。インジェクトされていないプリセットパラメータ、stateParamsをひとつ取ります。
$stateProvider.state('contacts', {
templateUrl: function ($stateParams){
return '/partials/contacts.' + $stateParams.filterBy + '.html';
}
})
Or you can use a template provider function which can be injected, has access to locals, and must return template HTML, like this:
もしくはテンプレートプロバイダ関数を使えます。インジェクト、ローカルへのアクセスができ、templateHTMLを返す必要があります。以下のように。
$stateProvider.state('contacts', {
templateProvider: function ($timeout, $stateParams) {
return $timeout(function () {
return '<h1>' + $stateParams.contactId + '</h1>'
}, 100);
}
})
If you'd like your <ui-view>
to have some default content before its populated by a state activation, you can do that as well. The contents will be replaced as soon as a state is activated and populates the ui-view with a template.
<ui-view>
にはデフォルトの値を入れておくことができます。コンテンツはステートがアクティブになると置き換えられます。
<body>
<ui-view>
<i>Some content will load here!</i>
</ui-view>
</body>
You can assign a controller to your template. Warning: The controller will not be instantiated if template is not defined.
テンプレートにコントローラーを割り当てることができます。テンプレートが定義されていない場合、コントローラがインスタンス化されることはありません。
You set your controller
like this:
下記のようにセットしてください。
$stateProvider.state('contacts', {
template: '<h1>{{title}}</h1>',
controller: function($scope){
$scope.title = 'My Contacts';
}
})
Or if you already have a controller
defined on the module, like this:
すでにコントローラーを定義してあれば下記のように書けます。
$stateProvider.state('contacts', {
template: ...,
controller: 'ContactsCtrl'
})
Alternatively using the controllerAs syntax the above become:
controllerAsも使えます。
$stateProvider.state('contacts', {
template: '<h1>{{contact.title}}</h1>',
controller: function(){
this.title = 'My Contacts';
},
controllerAs: 'contact'
})
and
$stateProvider.state('contacts', {
template: ...,
controller: 'ContactsCtrl as contact'
})
Or for more advanced needs you can use the controllerProvider
to dynamically return a controller function or string for you:
もしくは応用として、必要であればcontrollerProvider
を使うことができます。
$stateProvider.state('contacts', {
template: ...,
controllerProvider: function($stateParams) {
var ctrlName = $stateParams.type + "Controller";
return ctrlName;
}
})
Controllers can use the $scope.$on() method to listen for events fired by state transitions.
コントローラは$scope.$on()
メソッドを使って、ステート変異のイベントをキャッチできます。
Controllers are instantiated on an as-needed basis, when their corresponding scopes are created, i.e. when the user manually navigates to a state via a URL, $stateProvider will load the correct template into the view, then bind the controller to the template's scope.
コントローラの対応するスコープが生成された時、必要に応じてコントローラがインスタンス化されます。例えば、ユーザーが手動でURLを変更した時に、$stateProviderはビューの中に正しいテンプレートを読み込み、そしてテンプレートのスコープにコントローラをバインドします。
You can use resolve
to provide your controller with content or data that is custom to the state. resolve
is an optional map of dependencies which should be injected into the controller.
カスタムされたコンテンツやデータ付きのコントローラをステートに提供するために、resolve
を使えます。
If any of these dependencies are promises, they will be resolved and converted to a value before the controller is instantiated and the $stateChangeSuccess event is fired.
これらの依存関係のいずれかがpromiseである場合、コントローラがインスタンス化され、$stateChangeSuccessイベントが白化する前に、ある値にリゾルブ、コンバートされます。
The resolve
property is a map object. The map object contains key/value pairs of:
- key – {string}: a name of a dependency to be injected into the controller.
- factory - {string|function}:
- If string, then it is an alias for a service.
- Otherwise if function, then it is injected and the return value is treated as the dependency. If the result is a promise, it is resolved before the controller is instantiated and its value is injected into the controller.
resolve
プロパティはマップオブジェクトです。マップオブジェクトはキー/値のペアを含みます。
- key:{文字列}コントローラにインジェクトされる依存関係の名前
- factory:{文字列|関数}
- 文字列の場合、サービスのエイリアス。
- 関数の場合、注入され、返り値が依存関係として扱われます。結果がプロミスであれば、コントローラがインスタンス化される前にリゾルブされ、値はコントローラにインジェクトされます。
Examples: サンプル:
Each of the objects in resolve
below must be resolved (via deferred.resolve()
if they are a promise) before the controller
is instantiated. Notice how each resolve object is injected as a parameter into the controller.
下記のresolve
内にある各オブジェクトは、コントローラがインスタンス化される前に(もしプロミスであればdeferred.resolve
経由で)リゾルブされています。各リゾルブオブジェクトがどのようにコントローラにパラメータとしてインジェクトされるか注意してください。
$stateProvider.state('myState', {
resolve:{
// Example using function with simple return value.
// Since it's not a promise, it resolves immediately.
// シンプルな値を返す関数を用いた例
// プロミスではないので、直ちにリゾルブします。
simpleObj: function(){
return {value: 'simple!'};
},
// Example using function with returned promise.
// This is the typical use case of resolve.
// You need to inject any services that you are
// using, e.g. $http in this example
// プロミスを返す例
// リゾルブを使った典型的なケース
// 必要なサービスをインジェクトする必要がある。($httpなど)
promiseObj: function($http){
// $http returns a promise for the url data
return $http({method: 'GET', url: '/someUrl'});
},
// Another promise example. If you need to do some
// processing of the result, use .then, and your
// promise is chained in for free. This is another
// typical use case of resolve.
// 別のプロミスを用いたサンプル。
// 結果を処理する必要があるときに、 .then を使い、
// プロミスをチェインします。
// これは別の典型的なケースです。
promiseObj2: function($http){
return $http({method: 'GET', url: '/someUrl'})
.then (function (data) {
return doSomeStuffFirst(data);
});
},
// Example using a service by name as string.
// This would look for a 'translations' service
// within the module and return it.
// Note: The service could return a promise and
// it would work just like the example above
// 文字列名でサービスを用いる例。
// 'translations'サービスを探して返します。
// サービスはプロミスを返し、上記の用意扱えます。
translations: "translations",
// Example showing injection of service into
// resolve function. Service then returns a
// promise. Tip: Inject $stateParams to get
// access to url parameters.
// リゾルブ関数にサービスをインジェクションする例。
// サービスはプロミスを返す。
translations2: function(translations, $stateParams){
// Assume that getLang is a service method
// that uses $http to fetch some translations.
// Also assume our url was "/:lang/home".
return translations.getLang($stateParams.lang);
},
// Example showing returning of custom made promise
// カスタムプロミスを返す例。
greeting: function($q, $timeout){
var deferred = $q.defer();
$timeout(function() {
deferred.resolve('Hello!');
}, 1000);
return deferred.promise;
}
},
// The controller waits for every one of the above items to be
// completely resolved before instantiation. For example, the
// controller will not instantiate until promiseObj's promise has
// been resolved. Then those objects are injected into the controller
// and available for use.
controller: function($scope, simpleObj, promiseObj, promiseObj2, translations, translations2, greeting){
$scope.simple = simpleObj.value;
// You can be sure that promiseObj is ready to use!
$scope.items = promiseObj.data.items;
$scope.items = promiseObj2.items;
$scope.title = translations.getLang("english").title;
$scope.title = translations2.title;
$scope.greeting = greeting;
}
})
Learn more about how resolved dependencies are inherited down to child states.
リゾルブされた依存関係がどのように子のステートへ継承されたか知りたければここで。
You can attach custom data to the state object (we recommend using a data
property to avoid conflicts).
ステートオブジェクトにカスタムデータを与えることができます。(conflictを避けるためにdata
プロパティの使用を推奨します。)
// Example shows an object-based state and a string-based state
var contacts = {
name: 'contacts',
templateUrl: 'contacts.html',
data: {
customData1: 5,
customData2: "blue"
}
}
$stateProvider
.state(contacts)
.state('contacts.list', {
templateUrl: 'contacts.list.html',
data: {
customData1: 44,
customData2: "red"
}
})
With the above example states you could access the data like this: 上記の例で、このようにデータを取得できます。
function Ctrl($state){
console.log($state.current.data.customData1) // outputs 5;
console.log($state.current.data.customData2) // outputs "blue";
}
Learn more about how custom data properties are inherited down to child states.
There are also optional 'onEnter' and 'onExit' callbacks that get called when a state becomes active and inactive respectively. The callbacks also have access to all the resolved dependencies.
onEnter
とonExit
というコールバックがあります。ステートがアクティブ・非アクティブになった時に呼ばれます。全てのリゾルブした依存関係にアクセスできます。
$stateProvider.state("contacts", {
template: '<h1>{{title}}</h1>',
resolve: { title: 'My Contacts' },
controller: function($scope, title){
$scope.title = 'My Contacts';
},
onEnter: function(title){
if(title){ ... do something ... }
},
onExit: function(title){
if(title){ ... do something ... }
}
})
All these events are fired at the $rootScope
level.
下記のイベントは全て$rootScope
レベルで発火します。
- $stateChangeStart - fired when the transition begins.
- $stateChangeStart - 遷移開始時に発火.
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams){ ... })
Note: Use event.preventDefault() to prevent the transition from happening.
event.preventDefault() を使うことで誤った発火を防げます。
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams){
event.preventDefault();
// transitionTo() promise will be rejected with
// a 'transition prevented' error
})
-
$stateNotFound -
v0.3.0
- fired when a requested state cannot be found using the provided state name during transition. The event is broadcast allowing any handlers a single chance to deal with the error (usually by lazy-loading the unfound state). A specialunfoundState
object is passed to the listener handler, you can see its three properties in the example. Useevent.preventDefault()
to abort the transition (transitionTo() promise will be rejected with a 'transition aborted' error). For a more in-depth example on lazy loading states, see How To: Lazy load states -
$stateNotFound - 省略(多分ない時発火)
// somewhere, assume lazy.state has not been defined
$state.go("lazy.state", {a:1, b:2}, {inherit:false});
// somewhere else
$rootScope.$on('$stateNotFound',
function(event, unfoundState, fromState, fromParams){
console.log(unfoundState.to); // "lazy.state"
console.log(unfoundState.toParams); // {a:1, b:2}
console.log(unfoundState.options); // {inherit:false} + default options
})
-
$stateChangeSuccess - fired once the state transition is complete.
-
$stateChangeSuccess - 遷移完了時発火.
$rootScope.$on('$stateChangeSuccess',
function(event, toState, toParams, fromState, fromParams){ ... })
-
$stateChangeError - fired when an error occurs during transition. It's important to note that if you have any errors in your
resolve
functions (javascript errors, non-existent services, etc) they will not throw traditionally. You must listen for this $stateChangeError event to catch ALL errors. Useevent.preventDefault()
to prevent the $UrlRouter from reverting the URL to the previous valid location (in case of a URL navigation). -
$stateChangeError - 省略(多分エラーの時発火)
$rootScope.$on('$stateChangeError',
function(event, toState, toParams, fromState, fromParams, error){ ... })
- $viewContentLoading - fired once the view begins loading, before the DOM is rendered. The '$rootScope' broadcasts the event.
- $viewContentLoading - 読み込み開始時に一度だけ発火。DOMレンダリング前に呼ばれる。
$rootScope.$on('$viewContentLoading',
function(event, viewConfig){
// Access to all the view config properties.
// and one special property 'targetView'
// viewConfig.targetView
});
- $viewContentLoaded - fired once the view is loaded, after the DOM is rendered. The '$scope' of the view emits the event.
- $viewContentLoaded - 読み込み完了時に呼ばれる。
$scope.$on('$viewContentLoaded',
function(event){ ... });