2014-10-30 15 views
42

Với cách ban đầu để xác định bộ điều khiển, việc truy cập phạm vi của cha mẹ là khá tầm thường, vì phạm vi con được thừa kế từ cha mẹ.Truy cập phạm vi được thừa kế với Bộ điều khiển Theo cách tiếp cận

app.controller("parentCtrl", function($scope){ 
    $scope.name = "Parent"; 
}) 
.controller("childCtrl", function($scope){ 
    $scope.childName = "child of " + $scope.name; 
}); 

<div ng-controller="parentCtrl"> 
    {{name}} 
    <div ng-controller="childCtrl"> 
     {{childName}} 
    </div> 
</div> 

Controller-As cách tiếp cận có vẻ là recommended cách để khai báo một bộ điều khiển. Nhưng với Controller-As, cách tiếp cận trên không còn hoạt động nữa.

Chắc chắn, tôi có thể truy cập vào phạm vi phụ huynh với pc.name từ Xem:

<div ng-controller="parentCtrl as pc"> 
    {{pc.name}} 
    <div ng-controller="childCtrl as cc"> 
     {{cc.childName}} 
    </div> 
</div> 

tôi có một số vấn đề với điều này (tiềm năng cho mì spaghetti code), nhưng câu hỏi này là về việc truy cập phạm vi cha mẹ từ bộ điều khiển con.

Cách duy nhất tôi có thể thấy làm việc này là:

app.controller("parentCtrl", function(){ 
    this.name = "parent"; 
}) 
.controller("childCtrl", function($scope){ 
    $scope.pc.name = "child of " + $scope.name; 
    // or 
    $scope.$parent.pc.name = "child of " + $scope.name; 

    // there's no $scope.name 
    // and no $scope.$parent.name 
}); 

Vì vậy, bây giờ, điều khiển con cần biết về "pc" - ngoại trừ, điều này sẽ (trong tâm trí của tôi) bị hạn chế để xem. Tôi không nghĩ rằng một người điều khiển trẻ em nên biết về thực tế là một quan điểm quyết định tuyên bố một ng-controller="parentCtrl as pc".

Q: Cách tiếp cận đúng là gì?

EDIT:

Làm rõ: Tôi không tìm cách để thừa kế một bộ điều khiển cha mẹ. Tôi đang tìm cách kế thừa/thay đổi phạm vi chia sẻ. Vì vậy, nếu tôi đã sửa đổi các ví dụ đầu tiên, tôi sẽ có thể làm như sau:

app.controller("parentCtrl", function($scope){ 
    $scope.someObj = {prop: "not set"}; 
}) 
.controller("childCtrl", function($scope){ 
    $scope.someObj.prop = "changed"; 
}); 
+1

"Bộ điều khiển" của Angular thực sự là một "trình trợ giúp xem" hoặc "mô hình xem". Các hướng dẫn kiểu gợi ý sử dụng 'controllerAs' tích cực khuyến khích bạn sử dụng' pc' trực tiếp hoặc tô bóng trong tình huống này. Tôi cho rằng bạn có thể thiết lập chuỗi thừa kế giữa 'parentCtrl' và' childCtrl', ví dụ: 'childCtrl.prototype = Object.create (parentCtrl.prototype)' và sau đó trong constructor 'childCtrl' của bạn,' this.name' sẽ chỉ đến tên của cha mẹ trước khi bạn tô bóng nó. – Sacho

Trả lời

60

Sau khi nghiên cứu, tôi đến việc thực hiện sau đây:

Controller-Là cách tiếp cận KHÔNG phải là một thay thế cho việc sử dụng $scope. Cả hai đều có vị trí của họ, và có thể/nên được sử dụng cùng nhau một cách khôn ngoan.

  1. $scope thực hiện chính xác những gì tên của nó: tức là nó định nghĩa các thuộc tính ViewModel trên $scope. Điều này làm việc tốt nhất để chia sẻ phạm vi với bộ điều khiển lồng nhau có thể sử dụng $scope để điều khiển logic của riêng chúng hoặc thay đổi nó.
  2. Trình điều khiển-As xác định toàn bộ đối tượng bộ điều khiển dưới dạng một ViewModel với phạm vi được đặt tên (thông qua bí danh của bộ điều khiển).Điều này làm việc tốt nhất chỉ trong View (nhưng không phải bộ điều khiển khác), nếu View quyết định nếu nó muốn tham chiếu đến một ViewModel controller cụ thể.

Dưới đây là một ví dụ:

var app = angular.module('myApp', []); 
 

 
// Then the controllers could choose whether they want to modify the inherited scope or not: 
 
app.controller("ParentCtrl", function($scope) { 
 
    this.prop1 = { 
 
     v: "prop1 from ParentCtrl" 
 
    }; 
 
    $scope.prop1 = { 
 
     v: "defined on the scope by ParentCtrl" 
 
    }; 
 
    }) 
 
    .controller("Child1Ctrl", function($scope) {}) 
 
    .controller("Child2Ctrl", function($scope) { 
 
    // here, I don't know about the "pc" alias 
 
    this.myProp = $scope.prop1.v + ", and changed by Child2Ctrl"; 
 
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script> 
 

 
<body ng-app="myApp"> 
 
    <div ng-controller="ParentCtrl as pc"> 
 
    <div ng-controller="Child1Ctrl"> 
 
     <div>I know about the "pc" alias: {{pc.prop1.v}}</div> 
 
    </div> 
 
    <div ng-controller="Child2Ctrl as ch2"> 
 
     <div>I only care about my own ViewModel: {{ch2.myProp}}</div> 
 
    </div> 
 
    </div>

+2

Vì vậy, về cơ bản bạn nói rằng không khả thi để truy cập phạm vi của cha mẹ bên trong một đứa trẻ khi sử dụng "controller as"? Tôi không xem xét cách tiếp cận được liệt kê bởi OP ($ scope. $ Parent.pc.name) để khả thi. – d512

7

Bạn nên làm như sau:

html

<div ng-controller="ChildController as child"> 
    <button type="button" ng-click="child.sayMe()">Say me!</button> 
</div> 

js

var app = angular.module('myApp', []) 
app.controller('BaseController',function() { 
    this.me = 'Base'; 
    this.sayMe= function() { 
     alert(this.me); 
    } 
}); 
app.controller('ChildController', function($scope, $controller) { 
    var controller = $controller('BaseController as base', {$scope: $scope}); 
    angular.extend(this, controller); 
    this.me = 'Child'; 
}); 

hãy xem https://docs.angularjs.org/guide/controller

+0

Mục đích của tôi (xin lỗi, nếu nó không được chuyển tải đúng cách) không phải là kế thừa một bộ điều khiển cơ sở, mà là thừa kế phạm vi. Tôi không muốn biết bộ điều khiển cha nào đang ở đó - tôi chỉ muốn dựa vào phạm vi (theo ví dụ đầu tiên của tôi). –

+0

ok nên cách duy nhất tôi biết là sử dụng $ parent. $ Scope hoặc $ rootScope – Whisher

+0

@Whisher: nó thực sự hữu ích. Một câu hỏi về điều này. Nhu cầu đặt 'BaseController làm cơ sở' ở đây là gì? Tôi chỉ đơn giản có thể làm 'BaseController' ngay từ khi nào, mục đích là kế thừa các thuộc tính/phương thức. Hãy sửa tôi nếu tôi sai – jintoppy

1

Đối với bất cứ ai tìm cách để chỉ cần truy cập phạm vi cha mẹ lập trình, sử dụng dịch vụ $scope, tìm ra phạm vi phụ huynh, và truy cập vào tên được sử dụng cho phạm vi của cha mẹ là controllerAs, ví dụ:

$scope.$parent.someName.doSomething();

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