AngularJS - cách lấy tham chiếu kết quả được lọc ngRepeat


129

Tôi đang sử dụng lệnh ng-repeat với bộ lọc như vậy:

ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4"

và tôi có thể thấy kết quả được hiển thị tốt; bây giờ tôi muốn chạy một số logic về kết quả đó trong bộ điều khiển của tôi. Câu hỏi là làm thế nào tôi có thể lấy tài liệu tham khảo kết quả?

Cập nhật:


Chỉ cần làm rõ: Tôi đang cố gắng tạo tự động hoàn tất, tôi có đầu vào này:

<input id="queryInput" ng-model="query" type="text" size="30" placeholder="Enter query">

và sau đó kết quả được lọc:

<ul>
   <li  ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4">{{item.name}}</li>
</ul>

bây giờ tôi muốn điều hướng kết quả và chọn một trong các mục.

Câu trả lời:


270

CẬP NHẬT : Đây là một cách dễ dàng hơn so với những gì trước đây.

 <input ng-model="query">
 <div ng-repeat="item in (filteredItems = (items | orderBy:'order_prop' | filter:query | limitTo:4))">
   {{item}}
 </div>

Sau đó $scope.filteredItemscó thể truy cập.


Cảm ơn đã trả lời, xin vui lòng xem cập nhật của tôi. Làm thế nào bạn sẽ thực hiện điều đó, lưu ý rằng tôi nhận được toàn bộ danh sách các mục trên init
Shlomi Schwartz

siêu mát mẻ, cảm ơn vì điều đó. Tôi ước nó là một tính năng tích hợp của NG
Shlomi Schwartz

3
Vấn đề với cách tiếp cận này là nếu bạn xem thuộc tính được chỉ định, bạn sẽ kết thúc spam $ digest (mỗi lần lặp) ... Có thể có một số cách để tránh điều này?
Juho Vepsäläinen

1
Nếu tôi xem đối tượng tìm kiếm và console.log, filteredItemstôi luôn nhận được bộ lọc dữ liệu sau này. Đó không phải là kết quả của bộ lọc vừa thay đổi, mà là bộ lọc từ thay đổi trước đó. Có ý kiến ​​gì không?
Vấn

4
Ai đó có thể giải thích cho tôi, tại sao điều này làm việc? Tôi có thể hiểu rằng một biến từ phạm vi $, có thể truy cập được trong phạm vi lặp lại (kế thừa phạm vi), nhưng theo cách khác thì sao? Làm sao? Một số tài liệu được đánh giá cao. Cảm ơn
dalvarezmartinez1

30

Đây là phiên bản lọc của giải pháp của Andy Joslin.

Cập nhật: THAY ĐỔI THAY ĐỔI. Kể từ phiên bản 1.3.0-beta.19 ( bộ cam kết này ) không có ngữ cảnh và thissẽ bị ràng buộc trong phạm vi toàn cầu. Bạn có thể chuyển ngữ cảnh làm đối số hoặc sử dụng cú pháp răng cưa mới trong ngRepeat , 1.3.0-beta.17 +.

// pre 1.3.0-beta.19
yourModule.filter("as", function($parse) {
  return function(value, path) {
    return $parse(path).assign(this, value);
  };
});

// 1.3.0-beta.19+
yourModule.filter("as", function($parse) {
  return function(value, context, path) {
    return $parse(path).assign(context, value);
  };
});

Sau đó, theo quan điểm của bạn

<!-- pre 1.3.0-beta.19 -->
<input ng-model="query">
<div ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4 | as:'filteredItems'">
 {{item}}
</div>

<!-- 1.3.0-beta.19+ -->
<input ng-model="query">
<div ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4 | as:this:'filteredItems'">
 {{item}}
</div>

<!-- 1.3.0-beta.17+ ngRepeat aliasing -->
<input ng-model="query">
<div ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4 as filteredItems">
 {{item}}
</div>

Cung cấp cho bạn quyền truy cập vào $scope.filteredItems.


Cảm ơn! Bạn có thể giải thích làm thế nào mã bộ lọc hoạt động? Tôi không quen thuộc với $ parse và các tài liệu góc cạnh không giúp tôi giải mã cách bộ lọc của bạn hoạt động chính xác.
Magne

2
@Magne Không có vấn đề! Vui lòng kiểm tra bản cập nhật mặc dù nó có thể giúp bạn giảm bớt nỗi đau và đau khổ. Tóm lại, để trả lời câu hỏi của bạn $parsetrình biên dịch biểu thức của Angular .. Ví dụ: nó sẽ lấy chuỗi 'some.object.property' và trả về một hàm cho phép bạn đặt hoặc nhận giá trị tại đường dẫn đã nói cho một chỉ định bối cảnh. Tôi đang sử dụng nó để đặt kết quả lọc trên phạm vi $ ở đây, cụ thể. Tôi mong bạn trả lời câu hỏi này.
kevinjamesus86

23

Hãy thử một cái gì đó như thế này, vấn đề với ng-repeat là nó tạo ra phạm vi con vì bạn không thể truy cập

bộ lọc

từ bộ điều khiển

<li ng-repeat="doc in $parent.filteritems = (docs | filter:searchitems)" ></li>

16

Cập nhật:

Ngay cả sau 1.3.0. nếu bạn muốn đặt nó trên phạm vi điều khiển hoặc cha mẹ bạn không thể làm điều đó với như cú pháp. Ví dụ: nếu tôi có đoạn mã sau:

<div>{{labelResults}}</div>
<li ng-repeat="label in (labels | filter:query | as labelResults)">
</div>

ở trên sẽ không hoạt động. Cách để đi xung quanh nó là sử dụng $ cha như vậy:

<li ng-repeat="label in ($parent.labelResults = (labels | filter:query))">

Thật tốt khi lưu ý rằng nếu bạn có bộ lọc giới hạn về điều này. Nó sẽ không được phản ánh trong $ Parent.labelResults
Zack

Nếu tôi console.log labelResultsluôn nhận được bộ lọc dữ liệu sau này. Đó không phải là kết quả của bộ lọc vừa thay đổi, mà là bộ lọc từ thay đổi trước đó. Bạn không có vấn đề này?
Anna

10

Tôi đã đưa ra một phiên bản tốt hơn của giải pháp Andy. Trong giải pháp của mình, ng-repeat đặt một chiếc đồng hồ vào biểu thức có chứa bài tập. Mỗi vòng lặp digest sẽ đánh giá biểu thức đó và gán kết quả cho biến phạm vi.

Vấn đề với giải pháp này là bạn có thể gặp phải các vấn đề về chuyển nhượng nếu bạn ở trong phạm vi con. Đây là cùng một lý do tại sao bạn nên có một dấu chấm trong mô hình ng .

Một điều khác tôi không thích về giải pháp này là nó chôn vùi định nghĩa của mảng được lọc ở đâu đó trong phần đánh dấu khung nhìn. Nếu nó được sử dụng ở nhiều nơi trong chế độ xem của bạn hoặc bộ điều khiển của bạn, nó có thể gây nhầm lẫn.

Một giải pháp đơn giản hơn là chỉ đặt một chiếc đồng hồ trong bộ điều khiển của bạn trên một chức năng thực hiện nhiệm vụ:

$scope.$watch(function () {
    $scope.filteredItems = $scope.$eval("items | orderBy:'order_prop' | filter:query | limitTo:4");
});

Chức năng này sẽ được đánh giá trong mỗi chu kỳ tiêu hóa để hiệu suất phải tương đương với giải pháp của Andy. Bạn cũng có thể thêm bất kỳ số lượng bài tập nào trong hàm để giữ tất cả chúng ở một nơi thay vì phân tán về chế độ xem.

Trong chế độ xem, bạn sẽ chỉ sử dụng danh sách được lọc trực tiếp:

<ul>
    <li  ng-repeat="item in filteredItems">{{item.name}}</li>
</ul>

Đây là một câu đố trong đó điều này được hiển thị trong một kịch bản phức tạp hơn.


Siêu sạch và không gây ô nhiễm cấu trúc, tốt đẹp!
kuzyn

giải pháp này là hoàn hảo đối với tôi..tôi đã sử dụng lặp lại bộ sưu tập của ionic thay vì lặp lại..có lý do tại sao câu trả lời được chấp nhận không hiệu quả với tôi
Lakshay

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.