2014-11-23 15 views
24

Tôi có một ứng dụng mà tôi đang xây dựng với góc, tôi có khoảng 8-10 điểm để xây dựng ra. Tất cả các chế độ xem đều có chân trang được chia sẻ, dựa trên chế độ xem và một bộ quy tắc kinh doanh tôi cần phải hiển thị/ẩn một số nội dung trên chân trang có điều kiện.AngularJS: ng-bao gồm và ng-controller

So. Tôi có bộ điều khiển cho mỗi chế độ xem và sau đó một bộ điều khiển cho chân trang. Tôi bao gồm bố cục chân trang chung sử dụng ng-include, trong đó html tôi bao gồm tham chiếu bộ điều khiển chân trang trong bộ điều khiển ng.

index.html

<body ng-controller="MainCtrl as vm"> 
    <p>Message from Main Controller '{{vm.mainMessage}}'</p> 
    <div ng-include="'commonFooter.html'"></div> 
</body> 

commonFooter.html

<div ng-controller="FooterCtrl as vm"> 
    <p>Message from Footer Controller '{{vm.message}}'</p> 
    <p ng-show="vm.showSomthing">Conditional footer Content</p> 
</div> 

Tôi muốn mỗi bộ điều khiển xem để xác định trạng thái của chân và liệu nội dung cụ thể là ẩn hay không. (shouldDisplaySomthingInFooter bên dưới)

app.controller('MainCtrl', function($scope) { 
    var vm = this; 
    vm.mainMessage= 'HEELO'; 
    vm.shouldDisplaySomthingInFooter = true; 
    window.console.log('Main scope id: ' + $scope.$id); 
}); 

Sau đó, tôi đã có ý định rằng trong FooterController sẽ đạt trở lại vào bộ điều khiển phụ huynh và kéo ra các thiết lập cụ thể để cho phép/vô hiệu hóa nội dung dựa trên các quy tắc kinh doanh.

app.controller('FooterCtrl', function($scope) { 
    var vm = this; 
    vm.message = 'vm footer'; 

    window.console.log('Footer scope id: ' + $scope.$id); 
    window.console.log('Footer parent scope id: ' + $scope.$parent.$id); 
    window.console.log('Footer grandparent scope id: ' + $scope.$parent.$parent.$id); 
    window.console.log('Footer grandparent scope name: ' + $scope.$parent.$parent.mainMessage); 
    window.console.log('Footer grandparent scope condition: ' + $scope.$parent.$parent.shouldDisplaySomthingInFooter); 

    vm.showSomthing = false; //how to pull from parent scope to bind the ng-show to a value set in the parent from within a ng-include? 
}); 

Tôi có ví dụ này ở đây: http://plnkr.co/edit/ucI5Cu4jjPgZNUitY2w0?p=preview

Những gì tôi đang tìm kiếm là tôi khi tôi đạt được vào phạm vi cha mẹ phải rút ra khỏi nội dung nó sẽ trở lại như không xác định, và tôi không chắc chắn tại sao.

Tôi có thể thấy rằng các phạm vi được lồng vào cấp độ ông bà bằng cách kiểm tra phạm vi, tôi tin rằng điều này là do ng-include thêm một lớp phạm vi bổ sung bên dưới phạm vi xem. outout from console in attached example

Thêm điểm: Nếu tôi không thể phải sử dụng các đối tượng $ phạm vi và có thể gắn bó với var vm = this; cách để làm việc đó đó sẽ là một lợi thế. Nhưng người ăn xin không thể được chọn canh :)

app.controller('MainCtrl', function($scope) { 
    var vm = this; 

Cảm ơn bạn rất nhiều trước.

Trả lời

28

Nếu bạn phạm vi điều khiển bên ngoài của bạn như vm và bộ điều khiển bên trong của bạn như foo, bạn có thể sau đó tách chúng dễ dàng và tham khảo vm withi n bộ điều khiển bên trong.

Demo

HTML:

<body ng-controller="MainCtrl as vm"> 
    <p>Message from Main Controller '{{vm.mainMessage}}'</p> 
    <div ng-include="'commonFooter.html'"></div> 
</body> 

CommonFooter.html:

<div ng-controller="FooterCtrl as footer"> 
    <p>Message from Footer Controller '{{footer.message}}'</p> 
    <p ng-show="vm.shouldDisplaySomethingInFooter">Conditional footer Content</p> 
</div> 

app.js:

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

app.controller('MainCtrl', function() { 
    var self = this; 
    self.mainMessage = 'Hello world'; 
    self.shouldDisplaySomethingInFooter = true; 
}); 

app.controller('FooterCtrl', function() { 
    var self = this; 
    self.message = 'vm footer'; 
}); 

Lưu ý: Tôi đã đổi tên thành var vm = this thành var self = this để làm rõ và giảm sự nhầm lẫn giữa chế độ xem và bộ điều khiển của bạn.

sản lượng dự kiến:

output showing the conditionally hidden\shown items

3

Bạn đã hiểu sai điều khiển là cú pháp (see documentation) được sử dụng cho. Nó chỉ là một cách để lộ một bộ điều khiển cụ thể trên phạm vi cục bộ của bạn, để bạn có thể truy cập các thuộc tính của nó từ một khuôn mẫu. Khi bạn sử dụng someController as vm trong cả mẫu bố mẹ và chân trang, bạn không bằng cách nào đó tạo kết nối giữa các trình điều khiển hoặc bất kỳ thứ gì như thế. Bạn chỉ cần thiết lập thuộc tính vm trên phạm vi chân trang của bạn, vì vậy khi bạn sử dụng nó trong mẫu chân trang, bạn đang truy cập bộ điều khiển chân trang (và bạn đã chặn đường đến bộ điều khiển chính).

Đối với những gì bạn đang cố gắng làm, về cơ bản bạn không cần phải có bộ điều khiển là cú pháp. Chỉ cần đặt dữ liệu của bạn đúng cách trên $scope và để phân cấp phạm vi thực hiện phần còn lại cho bạn.

Trong điều khiển cha mẹ của bạn:

$scope.features.rock = true; 
$scope.features.roll = false; 

Trong mẫu chân của bạn

<p ng-show="features.rock">...</p> 
<p ng-show="features.roll">...</p> 

Bây giờ bạn cũng có thể xem và thay đổi features từ bộ điều khiển khác của bạn (phạm vi hoạt động của họ là hậu duệ của phạm vi điều khiển của cha mẹ).

2

Tôi fiddled xung quanh với plunker của bạn, mà còn thay đổi var vm = this;-$scope, vì vậy tôi không ở điểm thêm :-)

tôi sẽ tư vấn cho mạnh mẽ chống lại việc sử dụng $scope.$parent chính xác vì lý do bạn hiển thị. Các chỉ thị khác nhau như ng-include, ng-show v.v., tạo phạm vi của riêng chúng.

Bạn không có quyền kiểm soát nếu ai đó trong tương lai thay đổi html của bạn và thêm phạm vi, cố ý hoặc cách khác.

tôi khuyên bạn nên sử dụng chức năng mà nằm trên MainCtrl của bạn và truy cập chúng thông qua phạm vi kế thừa.

Plunker

$scope.getShouldShow = function() { 
    return $scope.shouldDisplaySomthingInFooter; 
    }; 
    $scope.setShouldShow = function(val) { 
    $scope.shouldDisplaySomthingInFooter = val; 
    }; 

    $scope.getMainMessage = function() { 
    return $scope.mainMessage; 
    } 

Và gọi họ:

<p ng-show="getShouldShow();">Conditional footer Content</p> 

Và:

window.console.log('Footer grandparent scope name: ' + $scope.getMainMessage()); 
    window.console.log('Footer grandparent scope condition: ' + $scope.getShouldShow());