5

アプリが読み込まれると、フィルターとサービスを角度付きで登録します。しかし、サービスがデータを返す前にフィルターが実行しようとしているため、アイテムコレクションがフィルターで吠えています。フィドルを持っていましたが、外部リソースであるため、フィドルで$httpを使用できるかどうかわかりません。これが私が持っているフィドル です。実際には機能しません。それはたくさんのことを経てきました。私の問題はタイミングだと思います。http応答を待つか、それ自体を「強制」しないようにフィルターが必要です。

私が今得たエラーは、フィルターが適用されている場所である「アイテムが未定義」の原因です。http呼び出しをサービスにマッシュアップしようとする前に、これは機能していました。しかし、私はそれが角度のある方法であり、「ただ遵守したい」と感じています。

コントローラが起動すると、データをフェッチするための呼び出しが行われます。

eventApi.async().then(function () {
    $scope.eventCollection = eventApi.data();
});

しかし、それが戻る前に、フィルターはhtmlに適用されます:

 <tr ng:repeat="event in events  | myEventFilter:ddlFilter |
       orderBy:sort.column:sort.descending">

フィドル

4

1 に答える 1

8

これは、いくつかの欠落した依存関係を修正する更新されたフィドルのフォークです(eventApiコントローラーに$timeout注入されない、サービスに注入されないeventApi)。私のコメントはこのコードに基づいています:http://jsfiddle.net/BinaryMuse/zww7e/1/

このフィドルは、あなたが投稿した問題「未定義のプロパティ「長さ」を読み取れません」に正常に到達します。一般に、フィルターはデフォルトでnull/未定義の値を処理できる必要があります。次のようなものを読み取るようにフィルタを変更するだけです。

return function (items, eventFilterType) {
  var arrayToReturn = [];
  if (items === undefined) return arrayToReturn;
  // ...
}

それはあなたの根本的な問題の世話をするはずです。フィドルはエラーなしで実行されるようになりましたが、正しく機能していないようです。私の知る限りでは、コントローラーのセクションでは$scope.eventCollectionなく、設定しているためです。この変更を行うと、データが実際にビューに表示されます。$scope.eventsif (live)

ただし、Angularの別のプロパティに興味があるかもしれません。で構築されたPromiseを使用する$qと、ビューをPromiseに直接バインドでき、ビューは、Promiseの解決された値にバインドしたかのようにビューを処理します。したがって、たとえば、次のことができます。

// in the service
$timeout(function () {
  deffered.resolve(fakeEvents); // <-- resolve with the data
}, 2000);
return deffered.promise;

// in the controller
if (live) {
  $scope.events = eventApi.async();
}

このテクニックを示すフィドルの更新バージョンは次のとおりです。http://jsfiddle.net/BinaryMuse/zww7e/2/

[アップデート]

コメントでJeffが指摘しているように、Angularは自動promiseアンラッピングを非推奨にしています。ここでコミットを確認できますが、メッセージは次のとおりです。

fix($ parse):promise unwrappingを廃止し、オプトインにします

このコミットにより、promise unwrappingが無効になり、開発者が必要に応じて機能をオンに戻すことができる$ parseProvider.unwrapPromises()getter /setterapiが追加されます。Promiseアンラッピングのサポートは将来Angularから削除され、この設定では移行期間中にのみ有効にすることができます。

アンラップが有効になっている場合、Angularはpromiseをアンラップする各式に関する警告をログに記録します(ノイズを減らすために、各式は1回だけログに記録されます)。このロギングを無効にするには、を使用します $parseProvider.logPromiseWarnings(false)

以前は、式の評価中に式のどこかに見つかったpromiseは、未解決の場合は未定義に評価され、実行された場合は実行値に評価されていました。

これは、主にテンプレートでのデータアクセス(生の値としてアクセス)とコントローラーコード(promiseとしてアクセス)の間の二分法のために、非常に有用または人気があることが証明されなかった機能です。

ほとんどのコードでは、コントローラーで手動で、またはこの方法でモデルアクセスをルーティングおよび統合することで自動的にpromiseを解決することになりました。

自動プロミスアンラッピングのその他の欠点:

  • コンポーネントを構築するときは、生の約束を受け取ることが望ましいことがよくあります
  • 複雑さが増し、式の評価が遅くなります
  • 生成する必要のあるコードの量が原因で、式コードの事前生成が魅力的でなくなります
  • IDEのオートコンプリートとツールのサポートを困難にします
  • あまりにも多くの魔法を追加します

重大な変更:$ parseおよび一般的なテンプレートは、promiseを自動的にアンラップしなくなりました。$parseProvider.unwrapPromises(true)この機能は廃止され、どうしても必要な場合は、 APIを介して移行期間中に再度有効にすることができます 。

于 2013-02-01T22:46:50.190 に答える