データシステムは、要素のモデルデータ(プロパティおよびサブプロパティ)に[監視可能な変更](https://github.com/jtakiguchi/polymer-docs-japanese-translation
/blob/master/docs/polymer2/data-system/data-system-concepts.md#observable-changes)を加えるためのメソッドを提供します。これらのメソッドを使用して、配列やオブジェクトのサブプロパティに監視可能な変更を加えます。
関連する概念:
- [データパス](https://github.com/jtakiguchi/polymer-docs-japanese-translation
/blob/master/docs/polymer2/data-system/data-system-concepts.md#data-paths) - [監視可能な変更](https://github.com/jtakiguchi/polymer-docs-japanese-translation
/blob/master/docs/polymer2/data-system/data-system-concepts.md#observable-changes)
パスの記法
[データパス](https://github.com/jtakiguchi/polymer-docs-japanese-translation
/blob/master/docs/polymer2/data-system/data-system-concepts.md#data-paths)は、パスセグメントの連続体です。ほとんどの場合、各パスセグメントはプロパティ名になります。データAPIでは二種類のパスが利用可能です。:
- ドット区切りのパスセグメントの文字列(下記例の一番目)
- 配列アイテムが文字列で、パスセグメント又はドット区切りのパスのいずれかになります。(下記例の三番目)
以下はすべて同じパスを表します。
"one.two.three"
["one", "two", "three"]
["one.two", "three"]
特別な種類のパスセグメントがいくつかあります。
- ワイルドカードパス(例:
foo.*
)は、配列の変更を含む、指定されたパスやそのサブプロパティに対するすべての変更を表します。 - 配列の変更パス(例:
foo.splices
)は、指定された配列に対するすべての変更を表す。 - 配列アイテムのパス(例:
foo.11
)は、配列内の特定のアイテムを表します。
パスによる値の取得
パスに基づいて値を取得するにはgetメソッドを使用してください。
// retrieve a subproperty by path
var value = this.get('myProp.subProp');
// Retrieve the 11th item in myArray
var item = this.get(['myArray', 11])
パスによるプロパティまたはサブプロパティの設定
サブプロパティに[監視可能な変更](https://github.com/jtakiguchi/polymer-docs-japanese-translation
/blob/master/docs/polymer2/data-system/data-system-concepts.md#observable-changes)を加えるにはsetメソッドを使用してください。
// clear an array
this.set('group.members', []);
// set a subproperty
this.set('profile.name', 'Alex');
プロパティまたはサブプロパティの値が変わらない場合には、set
を呼び出しても効果がありません。特に、オブジェクトのプロパティでset
を呼び出すと、オブジェクトそのものが変更されない限り、Polymerはオブジェクトのサブプロパティの変更を検知しません。同様に、配列プロパティでset
を呼び出した場合も、Polymerは既存の配列の変更を検知しません。
// DOES NOT WORK
this.profile.name = Alex;
this.set('profile', this.profile);
// DOES NOT WORK
this.users.push({name: 'Grace'});
this.set('users', this.users);
どちらの場合も、オブジェクトは変更されておらず、オブジェクトそのものに何ら効果が生じません。代わりに、notifyPathを利用でき、既に生じたサブプロパティの変更を、Polymerに知らせることができます。配列の場合には、配列の変更で説明したように、Polymerの配列変更メソッドを使用するか、配列の変更をPolymerに通知で説明したように、事後的にPolymerに通知する方法があります。
可変データ(MutableData):
Polymer.MutableData
ミックスインをインクルードした要素の場合、オブジェクトまたは配列上でset
を呼び出すと、オブジェクトや配列自身が変更されていなくても、Polymerはそれらオブジェクトや配列から開始して、オブジェクトグラフ全体を再評価します。詳細については、[MutableDataミックスインの使用](https://github.com/jtakiguchi/polymer-docs-japanese-translation
/blob/master/docs/polymer2/data-system/data-system-concepts.md#using-the-mutabledata-mixin)を参照してください。
関連タスク:
Polymerにサブプロパティの変更を通知する
オブジェクトのサブプロパティに変更を加えた後にnotifyPath
呼び出すことで、変更をデータシステムに対して[監視可能](https://github.com/jtakiguchi/polymer-docs-japanese-translation
/blob/master/docs/polymer2/data-system/data-system-concepts.md#observable-changes)にします。
this.profile.name = Alex;
this.notifyPath('profile.name');
notifyPath
を呼び出し時に、変更があった正確なパスを指定する必要があります。例えば、this.notifyPath('profile')
を呼び出ししてもprofile.name
に対する変更は検出しません。なぜならprofile
オブジェクトそのものは変更されていないからです。
可変データ(MutableData):
Polymer.MutableData
ミックスインをインクルードした要素の場合、オブジェクトまたは配列上でnotifyPath
を呼び出すと、オブジェクトや配列自身が変更されていなくても、Polymerはそれらオブジェクトや配列から開始して、オブジェクトグラフ全体を再評価します。詳細については、[MutableDataミックスインの使用](https://github.com/jtakiguchi/polymer-docs-japanese-translation
/blob/master/docs/polymer2/data-system/data-system-concepts.md#using-the-mutabledata-mixin)を参照してください。
配列との連携
Polymerの配列変更メソッドを使用して、配列に[監視可能な変更](https://github.com/jtakiguchi/polymer-docs-japanese-translation
/blob/master/docs/polymer2/data-system/data-system-concepts.md#observable-changes)を加えます。
ネイティブメソッド(Array.prototype.push
のような)を使用して配列を操作する場合、オブジェクトまたは配列へのバッチによる変更で説明しているように、変更を事後的にPolymerに通知することができます。
配列を変更
配列を変更するとき、PolymerはArray.prototype
を模倣した、一連の配列変更メソッドを提供しますが、最初の引数として文字列のpath
を使用する点が異なります。引数path
は、要素上で変更する配列を識別するのに利用され、第二引数以降はネイティブのArray
メソッドのものと同じです。
これらのメソッドは配列上で変更アクションを実行し、同じ配列にバインドされているかもしれない他の要素に対してその変更を通知します。配列を変更する際にこれらのメソッドを使用することで、(オブザーバー、算出プロパティ、またはデータバインディングを通じて)その配列を監視する全ての要素を同期された状態に保つことができます。
すべてのPolymer要素には、以下の配列変更メソッドがあり利用することができます。:
push(path, item1, [..., itemN])
pop(path)
unshift(path, item1, [..., itemN])
shift(path)
splice(path, index, removeCount, [item1, ..., itemN])
例
<link rel="import" href="components/polymer/polymer-element.html">
<link rel="import" href="components/polymer/src/elements/dom-repeat.html">
<dom-module id="x-custom">
<template>
<template is="dom-repeat" items="[[users]]">{{item}}</template>
</template>
<script>
class XCustom extends Polymer.Element {
static get is() {return 'custom-element'}
addUser(user) {
this.push('users', user);
}
removeUser(user) {
var index = this.users.indexOf(user);
this.splice('users', index, 1);
}
}
customElements.define(XCustom.is, XCustom);
</script>
</dom-module>
set
メソッドは、配列パスを使用して配列を操作する用途も利用できます。例えば、インデックス3
の配列のアイテムを置き換えるには次のようにします。:
this.set('users.3', {name: 'Churchill'});
たまにPolymerの配列変更メソッドの利用が役立たない場合もあります。この場合には、いくつかの選択肢があります。:
- notifySplicesメソッドを使用して事後的にPolymerに通知します。
-
MutableData
ミックスインを使用します。Polymer.MutableData
ミックスインをインクルードした要素の場合、オブジェクトまたは配列上でset
またはnotifyPath
を呼び出すと、オブジェクトや配列自身が変更されていなくても、Polymerはそれらオブジェクトや配列から開始して、オブジェクトグラフ全体を再評価します。詳細については、[MutableDataミックスインの使用](https://github.com/jtakiguchi/polymer-docs-japanese-translation
/blob/master/docs/polymer2/data-system/data-system-concepts.md#using-the-mutabledata-mixin)を参照してください。
配列の変更をPolymerに通知
可能である時は常に、Polymerの配列変更メソッドを利用すべきです。しかし、これらは必ずしも利用できるとは限りません。例えば、Polymer配列変更メソッドを使わないサードパーティのライブラリを利用しているかもしれません。これらのシナリオにおいては、変更後にnotifySplicesを呼び出すことで、配列を監視するすべてのPolymer要素にその変更が適切に通知されるようにできます。
notifySplices
メソッドは、配列の変更を一連のsplice
オペレーションに正規化することが求められます。例えば、配列上でshift
を呼び出して配列の最初の要素を削除するのは、splice(0, 1)
を呼び出すことと同じです。
splice
オペレーションはインデックスの順番に適用する必要があります。そうすることで要素が配列の内部表現を更新できます。
発生した正確な変更(パス)か分からない場合は、MutableData
ミックスインを利用できます。
Polymer.MutableData
ミックスインをインクルードした要素の場合、オブジェクトまたは配列上でset
またはnotifyPath
を呼び出すと、オブジェクトや配列自身が変更されていなくても、Polymerはそれらオブジェクトや配列から開始して、オブジェクトグラフ全体を再評価します。詳細については、[MutableDataミックスインの使用](https://github.com/jtakiguchi/polymer-docs-japanese-translation
/blob/master/docs/polymer2/data-system/data-system-concepts.md#using-the-mutabledata-mixin)を参照してください。
複数のプロパティ変更をバッチ処理
複数のプロパティへの変更をまとめて設定するにはsetProperties
を使用します。これにより、プロパティの変更はまとまったセットとして確実に設定されます。
this.setProperties({
date: 'Jan 17, 2017',
verified: true
});
同一オブジェクトへのパスをリンク
linkPathsメソッドは二つのパスを関連付けます。[二つのパスが同一のオブジェクトを参照](https://github.com/jtakiguchi/polymer-docs-japanese-translation
/blob/master/docs/polymer2/data-system/data-system-concepts.md##two-paths-referencing-the-same-object)での説明の通り、linkPaths
は要素が同じオブジェクトを参照する二つのパスを持つ場合に使用できます。
二つのパスがリンクされている場合、片方のパスへの[監視可能な変更](https://github.com/jtakiguchi/polymer-docs-japanese-translation
/blob/master/docs/polymer2/data-system/data-system-concepts.md#observable-changes)は、もう片方のパスでも同じように監視することができます。
linkPaths('selectedUser', 'users.1');
**どちらのパスも同一の要素に関連付ける必要があります。**要素間で変更を伝播するには、[データバインディング](https://github.com/jtakiguchi/polymer-docs-japanese-translation
/blob/master/docs/polymer2/data-system/data-binding.md)を使用すべきです。
パスの結合を解除するには、linkPaths
に渡した一つ目のパスを引数に指定してunlinkPaths
を呼び出します:
unlinkPaths('selectedUser');