Cập nhật biến phạm vi cha trong AngularJS


113

Tôi có hai bộ điều khiển, một bộ điều khiển được bọc trong một bộ điều khiển khác. Bây giờ tôi biết phạm vi con kế thừa thuộc tính từ phạm vi cha nhưng có cách nào để cập nhật biến phạm vi mẹ không? Cho đến nay tôi vẫn chưa tìm ra giải pháp rõ ràng nào.

Trong tình huống của tôi, tôi có bộ điều khiển lịch trong một biểu mẫu. Tôi muốn cập nhật ngày bắt đầu và ngày kết thúc từ phạm vi chính (là biểu mẫu) để biểu mẫu có ngày bắt đầu và ngày kết thúc khi được gửi.


có vẻ như bộ điều khiển lịch của bạn phải là một chỉ thị.
Jonah

Câu trả lời:


193

Bạn cần sử dụng một đối tượng (không phải đối tượng nguyên thủy) trong phạm vi cha và sau đó bạn sẽ có thể cập nhật nó trực tiếp từ phạm vi con

Cha mẹ:

app.controller('ctrlParent',function($scope){
    $scope.parentprimitive = "someprimitive";
    $scope.parentobj = {};
    $scope.parentobj.parentproperty = "someproperty";
});

Đứa trẻ:

app.controller('ctrlChild',function($scope){
    $scope.parentprimitive = "this will NOT modify the parent"; //new child scope variable
    $scope.parentobj.parentproperty = "this WILL modify the parent";
});

Bản demo làm việc : http://jsfiddle.net/sh0ber/xxNxj/

Xem Các sắc thái của kế thừa nguyên mẫu / nguyên mẫu phạm vi trong AngularJS là gì?


1
Tôi gặp lỗi này khi cố gắng triển khai điều này: 'Không thể đặt thuộc tính' parentproperty 'của undefined'.
Malcr001

Bạn có thể gửi mã của bạn? Nó đang hoạt động trong bản demo fiddle. Nếu điều khiển lịch của bạn sử dụng phạm vi cô lập, nó sẽ không kế thừa từ phạm vi chính, vì vậy bạn cần phải chuyển giá trị vào phạm vi của chỉ thị.
Dan

Xin lỗi tôi đã quên về câu hỏi này. Tôi đã chấp nhận nó vì cuối cùng tôi đã cố gắng làm cho nó hoạt động với sự trợ giúp của câu trả lời này.
Malcr001

Tôi hiểu việc đặt {{parentobj.parentproperty}} trong phần tử ctrlParent div là những gì khai báo đối tượng parentobj và đặt đối tượng này ở trong phạm vi ctrlParent. Đây có phải là một giả định chính xác?
Stephane

1
Cảm ơn, điều này hoạt động! Tôi chắc chắn nên đọc về điều này (sự kế thừa nguyên mẫu và nguyên thủy). Bạn có thể giới thiệu một bài đọc hay giải thích nhiều hơn một chút so với liên kết SO của bạn không?
jvannistelrooy 19/09

116

Có một cách nữa để thực hiện tác vụ này và không sử dụng $scope.$parentbiến.

Chỉ cần chuẩn bị một phương thức để thay đổi giá trị trong phạm vi chính và sử dụng nó trong phạm vi con. Như thế này:

app.controller('ctrlParent',function($scope) {
  $scope.simpleValue = 'x';
  $scope.changeSimpleValue = function(newVal) {
    $scope.simpleValue = newVal;
  };
});

app.controller('ctrlChild',function($scope){
    $scope.changeSimpleValue('y');
});

Nó cũng hoạt động và cung cấp cho bạn nhiều quyền kiểm soát hơn đối với các thay đổi giá trị.

Sau đó bạn cũng có thể gọi phương thức ngay cả trong HTML như: <a ng-click="changeSimpleValue('y')" href="#">click me!</a>.


1
Giải pháp tốt! điều này hoạt động vì khi không tìm thấy thứ gì đó trong $ scope hiện tại, Angular sẽ tìm kiếm trong $ cha. docs.angularjs.org/guide/scope (xem 'Phân cấp phạm vi').
Elo

Tôi thích câu trả lời này, không cần tạo đối tượng không cần thiết.
grimmdude

3
Độc giả tương lai: Tất cả các nhận xét cao năm này đều hơi sai lầm. Tạo hai hàm setter (là "các đối tượng không cần thiết") cho mọi biến là một cách thừa kế rườm rà và không cần thiết và không phải là cách Angular. Misko Hevery, người tạo ra Angular, có một bài nói chuyện trong đó anh ấy dạy "Bất cứ khi nào bạn có mô hình ng, thì ở đâu đó phải có một dấu chấm. Nếu bạn không có dấu chấm, bạn đang làm sai." Video Misko @ 29:19
Dan

làm cách nào để áp dụng giải pháp này bằng cách sử dụng cú pháp controllerAS?
niran

6

Điều này cũng hoạt động (nhưng không chắc liệu điều này có tuân theo phương pháp hay nhất hay không)

app.controller('ctrlParent',function($scope) {
    $scope.simpleValue = 'x';
});

app.controller('ctrlChild',function($scope){
    $scope.$parent.simpleValue = 'y';
});

1
Bạn nói đúng, sử dụng $ scope. $ Parent.value sẽ hoạt động trong hầu hết các trường hợp, tuy nhiên thường không phải là ý tưởng tốt nhất để sử dụng rộng rãi vì nó có thể khó quản lý trong các dự án lớn hơn, phức tạp hơn.
Alex Johnson

4

Khi bạn gán một thuộc tính nguyên thủy cho một phạm vi, nó luôn là cục bộ cho phạm vi (có thể được tạo nhanh chóng), ngay cả khi một phạm vi cha có một thuộc tính trùng tên. Đây là một quyết định thiết kế, và một IMHO tốt.

Nếu bạn cần thay đổi một số nguyên thủy (ints, boolean, string) trong phạm vi chính, từ dạng xem, bạn cần nó là một thuộc tính của một đối tượng khác trong phạm vi đó, vì vậy phép gán có thể đọc:

<a ng-click="viewData.myAttr = 4">Click me!</a>

và đến lượt nó sẽ:

  1. lấy viewDatađối tượng từ bất kỳ phạm vi nào mà nó được xác định trong
  2. gán 4 cho myAttrthuộc tính của nó .

4

Để truy cập các biến được khai báo trong tệp cha, chúng ta nên sử dụng $ cha trong bộ điều khiển con hoặc tệp mẫu

Trong bộ điều khiển

$scope.$parent.varaiable_name

Trong mẫu html

ng-model="$parent.varaiable_name"
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.