状況:
Ui-selectを使用する必要があるangularアプリを作成しています:ユーザー情報ページで、selectで1つまたは複数のタグを選択できる必要があります。既存のタグを取得して表示するのに問題があるという事実から。
コード:
表示:
<ui-select multiple ng-model="info_data.tags" theme="bootstrap" ng-disabled="disabled">
<ui-select-match placeholder="Select tag...">{{$item.name}} </ui-select-match>
<ui-select-choices repeat="tag in all_tags | propsFilter: {name: $select.search}">
{{tag.name}}
</ui-select-choices>
</ui-select>
<p>Selected: {{info_data.tags}}</p>
コントローラー:
$http({
url: base_url + 'main/db_get_all_tags',
method: "POST",
}).success(function (data) {
$scope.all_tags = data;
});
$scope.show_info = function() {
var result_info = DbService.get_info( $stateParams.db_data_id );
result_info.then( function( data )
{
$scope.info_data = data;
});
};
試行1:
これは非常に奇妙な動作です。ユーザーの情報ページにも、ui-selectにもタグが表示されません。 5/6回更新する場合を除いて、突然それは魔法のように機能し、ユーザー情報ページとui-selectにタグを表示します。どちらの場合も、機能していても機能していなくても、同じ種類のエラーメッセージがいくつか表示されます。
未定義のプロパティ「長さ」を読み取ることができません。
アテンプト2:
この問題を解決するために、コントローラーに次のコードを追加しました。
$scope.info_data = { tags: [] };
$scope. all_tags = [];
そして、私はもうエラーメッセージを受け取りません。アプリは安定しており、ユーザー情報ページで適切なタグを確認できます。唯一の問題は、タグがui-selectにロードされなくなったことです。
新しいタグを選択すると正常に機能しますが、既存のタグが失われます。
QUESTION(s):
Ui-selectを正しく機能させるにはどうすればよいですか? (現在v0.8.3)競合の問題はありますか?
サーバーから既存のデータを適切に呼び出すにはどうすればよいですか?
どうもありがとうございました!
あなたはあなたが見ているエラーについて特に説明していないので、以下が役立つかどうかはわかりません。
彼らが書いたカスタムフィルターであるpropsFilterフィルターを使用しているため、例としてui-selectデモコードを使用するときに最初に問題がありましたデモの場合:
<ui-select-choices repeat="tag in all_tags | propsFilter: {name: $select.search}">
このフィルターをコードに含めていないことを前提としています。これが問題が発生している理由である可能性があります。 Angularの法線filterを使用して解決できます:
<ui-select-choices repeat="tag in all_tags | filter: {name: $select.search}">
または、フィルタリングするプロパティが複数ある場合は、propsFilterフィルタを記述して、ANDではなくOR)でフィルタリングできます。「filter」を使用して複数のプロパティをフィルタリングすると、検索値の照合が試行されます。すべてのプロパティにわたって。
app.filter('propsFilter', function() {
return function(items, props) {
var out = [];
if (angular.isArray(items)) {
items.forEach(function(item) {
var itemMatches = false;
var keys = Object.keys(props);
for (var i = 0; i < keys.length; i++) {
var prop = keys[i];
var text = props[prop].toLowerCase();
if (item[prop].toString().toLowerCase().indexOf(text) !== -1) {
itemMatches = true;
break;
}
}
if (itemMatches) {
out.Push(item);
}
});
} else {
// Let the output be the input untouched
out = items;
}
return out;
};
});
ここでフィルターを含むコミットを確認できます: https://github.com/angular-ui/ui-select/commit/3fac88cfad0ad2369c567142eadba52bdb7998b1
ただし、特定のフィルタリング要件がある場合は、最適なパフォーマンスを確保するために独自のフィルターを作成することをお勧めします。
Select2#4.0以前の状況はわかりませんが、angular-ui-select
なしで使用するのはそれほど難しいことではありません(依存関係が1つ少なくなります)
バウアー依存関係にselect2
を含め、ディレクティブ内のlink
関数で使用するだけです。
.directive('someDirective', function() {
return {
restrict: 'E',
link: function(scope, element, attrs) {
element.find('.your-select2').select2({
theme: 'classic',
placeholder: 'Select a placeholder...',
allowClear: true,
data: [{ id: 'New', text: 'New'}]...
});
},
};
})
およびHTML:
<select class="your-select2" ng-model="a.model.field"></select>
必要に応じて、サービスを介してコントローラーからdata
をロードし、scope
を使用して設定することもできます。
私がangular-ui-select
を使ってみたとき、私はこれを言っています。さらに、ドキュメントはあまり役に立ちませんでした(怠惰と呼んでくださいがねえ)
PropsFilterを少し最適化しました。やっている
props[prop].toLowerCase();
アイテムの反復内ですが、これは実際には、プロパティの数倍だけ評価する必要があります。現在評価されていますitems count * props count
。
したがって、最終的に最適化されたコードは次のようになります。
app.filter('casinoPropsFilter', function() {
return function(items, props) {
var out = [];
if (angular.isArray(items)) {
var keys = Object.keys(props);
var propCache = {};
for (var i = 0; i < keys.length; i++) {
var prop = keys[i];
var text = props[prop].toLowerCase();
propCache[props[prop]] = text;
}
items.forEach(function(item) {
var itemMatches = false;
for (var i = 0; i < keys.length; i++) {
var prop = keys[i];
var text = propCache[props[prop]];
if (item[prop].toString().toLowerCase().indexOf(text) !== -1) {
itemMatches = true;
break;
}
}
if (itemMatches) {
out.Push(item);
}
});
} else {
// Let the output be the input untouched
out = items;
}
return out;
};
});