2012-10-19 21 views
31

Tôi đang học angularjs và tôi muốn có thể cho phép người dùng nhập nhiều đầu vào. Khi các đầu vào này được nhập vào, các thành phần mảng list sẽ thay đổi tương ứng. Tôi muốn thử sử dụng chỉ thị ngRepeat nhưng tôi đọc rằng kể từ khi nó tạo ra một phạm vi mới Tôi không thể DataBind:Cách angularjs để databind nhiều đầu vào là gì?

<div ng-repeat="item in list"> 
    <label>Input {{$index+1}}:</label> 
    <input ng-model="item" type="text"/> 
</div> 

tôi đã tự hỏi nếu tôi nên sử dụng một chỉ thị tùy chỉnh để làm điều này hoặc tiếp cận nó một cách khác nhau.

+2

Nếu một hộp nhập liệu sẽ hoạt động, với mỗi mục được phân tách bằng dấu phân tách, hãy xem ngList. http://docs.angularjs.org/api/ng.Chỉ thị: ngList –

+0

Mặc dù nó không trực quan cho những gì tôi đang phát triển, Thật tốt khi biết góc cạnh có tính năng này như một chỉ thị mà tôi có thể sử dụng trong tương lai. Cảm ơn! – rcell

Trả lời

37

Bạn sẽ có may mắn hơn nếu list của bạn là một mảng các đối tượng (trái ngược với một mảng nguyên thủy). Đây hoạt động tốt mặc dù một phạm vi mới được tạo ra với ng-repeat:

<div ng-repeat="item in list"> 
    <label>Input {{$index+1}}:</label> 
    <input ng-model="item.value" type="text"/> 
</div> 

với một bộ điều khiển của:

function TestController($scope) { 
    $scope.list = [ { value: 'value 1' }, { value: 'value 2' }, { value: 'value 3' } ]; 
}​ 

Xem this fiddle làm ví dụ. Mặt khác, nếu bạn đang cố gắng liên kết với một chuỗi các phạm vi mới sẽ gây ra một vấn đề như các giá trị bạn đang sửa đổi sẽ không được gắn với các chuỗi gốc ban đầu chuỗi (như trong ví dụ this fiddle).

86

Lý do dữ liệu liên quan đến một mục "nguyên thủy" không hoạt động là do cách thức ng-lặp lại tạo ra phạm vi con cho từng mục. Đối với mỗi mục, ng-repeat có phạm vi con mới được thừa kế từ phạm vi cha mẹ (xem các đường đứt nét trong hình bên dưới), và sau đó nó gán giá trị của mục cho một thuộc tính mới trên phạm vi con (các mục màu đỏ trong hình bên dưới). Tên của thuộc tính mới là tên của biến vòng lặp. Từ số ng-repeat source code:

childScope = scope.$new(); 
... 
childScope[valueIdent] = value; 

Nếu mục là nguyên thủy, thuộc tính phạm vi con mới về cơ bản được gán một bản sao giá trị nguyên thủy. Thuộc tính phạm vi con này không hiển thị với phạm vi cha mẹ và các thay đổi bạn thực hiện cho trường nhập được lưu trữ trong thuộc tính phạm vi con này. Ví dụ, giả sử chúng ta có trong phạm vi mẹ

$scope.list = [ 'value 1', 'value 2', 'value 3' ]; 

Và trong HTML:

<div ng-repeat="item in list"> 

Sau đó, phạm vi đứa con đầu lòng sẽ có item tài sản sau đây, với một giá trị nguyên thủy (value 1):

item: "value 1" 

ng-repeat with primitives

Do dữ liệu mô hình ng, các thay đổi bạn thực hiện cho trường nhập của biểu mẫu được lưu trữ trong thuộc tính phạm vi con đó.

Bạn có thể xác minh điều này bằng cách đăng nhập phạm vi con vào bảng điều khiển.Thêm vào HTML của bạn, bên trong ng-repeat:

<a ng-click="showScope($event)">show scope</a> 

Thêm vào bộ điều khiển của bạn:

$scope.showScope = function(e) { 
    console.log(angular.element(e.srcElement).scope()); 
} 


Với @ phương pháp huyền ảo, mỗi phạm vi con vẫn nhận được một mới "mục" tài sản, nhưng vì danh sách bây giờ là một mảng các đối tượng, childScope[valueIdent] = value; kết quả trong giá trị của thuộc tính mục được đặt thành tham chiếu đến một trong các đối tượng mảng (không phải là bản sao).

ng-repeat with objects

Sử dụng kỹ thuật showScope(), bạn sẽ thấy rằng phạm vi con giá trị item sở hữu của tài liệu tham khảo một trong những đối tượng mảng - nó không còn là một giá trị nguyên thủy.

Xem thêm don't bind to primitives in ng-repeat child scopes
What are the nuances of scope prototypal/prototypical inheritance in AngularJS? (có chứa hình ảnh về phạm vi trông như thế nào khi sử dụng ng lặp lại).

+8

Các sơ đồ thật tuyệt vời! – nh2

+0

hey người đàn ông phần mềm nào bạn đã sử dụng để hiển thị các biểu đồ ở trên? – abbood

+8

@abbood, [tag: GraphViz]. –

1

Đây là cách để thực hiện. Tôi đã sử dụng textareas và một cấu trúc khác với bộ lặp của mình, nhưng khái niệm chính là:

  • hiển thị giá trị đơn giản dựa trên chỉ mục. (Không ràng buộc)
  • trên mờ cập nhật mô hình
  • trên mô hình cập nhật lại làm

Nó được về cơ bản, giả mạo các ràng buộc.

fiddle làm việc - http://jsfiddle.net/VvnWY/4/

Các html:

<script type="text/ng-template" id="textareas.html"> 
    <textarea ng-if="strings" ng-repeat="str in strings" ng-blur="blur($event, $index)">{{strings[$index]}}</textarea> 
    </script> 

<div ng-controller="MyCtrl"> 
    Here's a few strings: <br /> 
    <div ng-repeat="str in strings">{{strings[$index]}}</div> 

    Here's the strings as editable (twice so that you can see the updates from a model change): <br /> 
    <form-textareas strings="strings"></form-textareas> 
    <form-textareas strings="strings"></form-textareas> 

</div> 

Các JS:

var myApp = angular.module('myApp',[]); 
angular.module('myApp', []) 
    .controller('MyCtrl', ['$scope', function($scope) { 
    $scope.strings = [ "foo", "bar", "cow" ]; 
    }]) 
    .directive('formTextareas', function() { 
    return { 
     restrict: "E", 
     scope: { 
      strings: '=' 
     }, 
     templateUrl: "textareas.html", 
     link: function($scope){ 
      $scope.blur = function($event, $index){ 
       $scope.strings[ $index ] = $event.currentTarget.value; 
      }; 
     } 
    }; 
    }) 
; 
3

Tôi tìm thấy một cách thú vị để làm điều này và nó cho phép tôi làm việc trên một loạt các nguyên thủy.

Tôi đang sử dụng AngularJS 1.2.1, đó là phiên bản duy nhất tôi có thể làm công việc này trong

HTML:.

<div ng-repeat="item in list"> 
    <label>Input {{$index+1}}:</label> 
    <input ng-model="item" type="text" ng-blur="editItem($index, item)"/> 
</div> 

JavaScript:

$scope.editItem = function(idx, eItem) { 
    $scope.list[idx] = eItem; 
}; 

Link: http://jsfiddle.net/bxD2P/10/ (cảm ơn Gloopy cho người khởi xướng Fiddle)

Tôi chắc rằng có những cách dễ dàng để chọc thủng lỗ hổng về cách thức hoạt động của nó, và tôi rất thích nghe chúng. Nó sẽ cho phép tôi cập nhật mã của tôi.

Các vấn đề liên quan